所谓的Shiro认证,其实就是用户登录。控制某些页面登录可见,不登录则自动重定向到登录页面。
源码下载
一、导入项目所需要的jar
二、配置web.xml
在web.xml中需要配置spring和springmvc以及shiro。
shiro-2
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
spring
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
1
spring
/
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/*
三、配置springmvc.xml
主要配置了URL前后缀和注解扫描。
四、配置applicationContext.xml
配置shiro,在这里直接模拟了两个用户,并没有连接数据库进行取值验证。
/login.jsp = anon
/shiroCtrl/login = anon
/shiroCtrl/logout = logout
# everything else requires authentication:
/** = authc
五、Realm:
Realm:域,Shiro 从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource , 即安全数据源。
ShiroRealm.java:
package com.mfc.realms;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;
public class ShiroRealm extends AuthenticatingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("[FirstRealm] doGetAuthenticationInfo");
//1、把AuthenticationToken 转换为UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
//2、从UsernamePasswordToken 中获取username
String username = upToken.getUsername();
//3、调用数据库方法,从数据库中查询username 对应的用户记录
System.out.println("从数据库中获取username:" + username + " 所对应的用户信息");
//4、若用户不存在,则可以抛出UnknowAccountException异常
if("unknow".equals(username)){
throw new UnknownAccountException("影虎不存在");
}
//5、根据用户的信息情况,决定是否需要抛出其他的AuthenticationException异常
if("monster".equals(username)){
throw new LockedAccountException("用户被锁定");
}
//6、根据用户的情况,来构建AuthenticationInfo对象并返回,通常使用实现类是SimpleAuthenticationInfo
//以下信息是从数据库中获取的
//1、principal:认证的实体信息,可以使username,也可以是数据表对应的用户的实体类对象
Object principal = username;
//2、credentials:密码
Object credentials = null; //fc1709d0a95a6be30bc5926fdb7f22f4
if("admin".equals(username)){
credentials = "038bdaf98f2037b31f1e75b5b4c9b26e";
}else if("user".equals(username)){
credentials = "098d2c478e9c11555ce2823231e02ec1";
}
//3、realmName:当前realm对象的name,调用父类的getName()即可
String realmName = getName();
//4、盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
return info;
}
public static void main(String[] args) {
String algorithmName = "MD5";
Object source = "123456";
Object salt = ByteSource.Util.bytes("user");
int hashIterations = 1024;
Object result = new SimpleHash(algorithmName, source, salt, hashIterations);
System.out.println(result);
}
}
SecondRealm.java:
package com.mfc.realms;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;
public class SecondRealm extends AuthenticatingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("[SecondReaml] doGetAuthenticationInfo");
//1、把AuthenticationToken 转换为UsernamePasswordToken
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
//2、从UsernamePasswordToken 中获取username
String username = upToken.getUsername();
//3、调用数据库方法,从数据库中查询username 对应的用户记录
System.out.println("从数据库中获取username:" + username + " 所对应的用户信息");
//4、若用户不存在,则可以抛出UnknowAccountException异常
if("unknow".equals(username)){
throw new UnknownAccountException("影虎不存在");
}
//5、根据用户的信息情况,决定是否需要抛出其他的AuthenticationException异常
if("monster".equals(username)){
throw new LockedAccountException("用户被锁定");
}
//6、根据用户的情况,来构建AuthenticationInfo对象并返回,通常使用实现类是SimpleAuthenticationInfo
//以下信息是从数据库中获取的
//1、principal:认证的实体信息,可以使username,也可以是数据表对应的用户的实体类对象
Object principal = username;
//2、credentials:密码
Object credentials = null; //fc1709d0a95a6be30bc5926fdb7f22f4
if("admin".equals(username)){
credentials = "ce2f6417c7e1d32c1d81a797ee0b499f87c5de06";
}else if("user".equals(username)){
credentials = "073d4c3ae812935f23cb3f2a71943f49e082a718";
}
//3、realmName:当前realm对象的name,调用父类的getName()即可
String realmName = getName();
//4、盐值
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
return info;
}
public static void main(String[] args) {
String algorithmName = "SHA1";
Object source = "123456";
Object salt = ByteSource.Util.bytes("admin");
int hashIterations = 1024;
Object result = new SimpleHash(algorithmName, source, salt, hashIterations);
System.out.println(result);
}
}