1.web.xml中加入shiro的过滤器:
<!--shiro的代理过滤器--> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.shiro的配置 applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!--spring创建shiro的核心对象securityManager--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--确定使用的realm--> <property name="realm" ref="jpaRealm"/> </bean> <!--创建自定义realm--> <bean id="MyRealm" class="cn.itsource.commerce.realm.MyRealm"> <!--密码适配器--> <property name="credentialsMatcher"> <!-- The 'bootstrapDataPopulator' Sha256 hashes the password (using the username as the salt) then base64 encodes it: --> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <!--加密方式--> <property name="hashAlgorithmName" value="MD5"/> <!--加密次数--> <property name="hashIterations" value="10"/> </bean> </property> </bean> <!--开启shiro的注解权限支持--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <!--该bean的id必须和web.xml中的<filter-name>保持一致--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--登录的url地址,如果没有认证通过,统一跳到value对应的页面--> <property name="loginUrl" value="/login"/> <!--登录成功的url地址,如果认证通过,统一跳到value对应的页面--> <property name="successUrl" value="/main"/> <!--如果没有权限,统一跳到value对应的页面--> <property name="unauthorizedUrl" value="/shiro/unauthorized.jsp"/>
<!-- 权限配置 --> <property name="filterChainDefinitions"> <value> <!-- anon无权限访问请求,此处是登录页面和登录请求 --> /login = anon /static/**=anon <!-- 需要权限为add的用户才能访问此请求--> /user=perms[user:add] <!-- 需要管理员角色才能访问此页面 --> /user/add=roles[admin] <!--拦截非静态资源的所有请求--> /** = authc </value> </property> </beans>
3.自定义Realm,实际应用中一般都是自定义Realm
//自定义Realm一定要继承AuthorizingRealm
public class MyRealm extends AuthorizingRealm{
//权限
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取用户名
String username =(String )principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//授予角色
Set<String> roles = getRolesByUsername(username);
info.addRoles(roles);
//授予权限
Set<String> permission = getPermissionByUsername(username);
info.setStringPermissions(permission);
return info;
}
//模拟数据库中的角色
public Set<String> getRolesByUsername(String username){
Set<String> roles=new HashSet<String>();
roles.add("r1");
roles.add("r2");
roles.add("r3");
roles.add("r4");
return roles;
}
//模拟数据库中的权限
public Set<String> getPermissionByUsername(String username){
Set<String> permission=new HashSet<String>();
permission.add("employee:*");
permission.add("department:save");
permission.add("date:save:delete");
return permission;
}
//认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//前端传过来的令牌
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//前端传的用户名
String username = token.getUsername();
//在数据库中去查找用户名对应的密码
String password = findByUserName(username);
if(password==null){
return null;//为什么返回null--->底层会自动抛出 未知账号异常
}
//返回认证信息
/**
* Object principal 前端传过来的密码
* Object credentials 数据库中查询的密码
* String realmName 当前Realm的名字
*/
//盐值
ByteSource itsource = ByteSource.Util.bytes("itsource");
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,itsource,getName());
return info;
}
//模拟数据库中的数据
public String findByUserName(String username){
if("root".equals(username)){
return "123";
}
return null;
}
}