简述:用户通过subject登陆,形成一个UsernamePasswordToken,令牌,在域realm里完成认证、授权,成功后加入缓存。(realm可以写、也可以用默认的,也可以写很多个域)
image快速入门
登陆顺序
1、获取登录凭证
//1 创建安全管理器
SecurityManager manager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
//2 绑定SecurityManager到SecurityUtils
SecurityUtils.setSecurityManager(manager);
//3 封装用户名和密码成为一个登录令牌(通行证)
UsernamePasswordToken token=new UsernamePasswordToken("用户名","密码");
2、提交凭证
//4 登录校验
Subject subject = SecurityUtils.getSubject();//获取用户实体(例如从数据库,或者ini配置文件)
3、处理登录结果
try {
subject.login(token);
} catch ( UnknownAccountException uae ) {
} catch ( IncorrectCredentialsException ice ) {
} catch ( LockedAccountException lae ) {
} catch ( ExcessiveAttemptsException eae ) {
}
} catch ( AuthenticationException ae ) {
}
1、登录
SecurityManager manager = new IniSecurityManagerFactory("classpath:shiro.ini").getInstance();
SecurityUtils.setSecurityManager(manager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken("用户名","密码");
subject.login(token);
token.setRememberMe(true);//记住我,必须使用user过滤器(登陆或记住我),这里不能用authc(登陆)
2、实际身份认证
subject委托给securityManager,调用securityManager.login(token)
3、认证
SecurityManager接收令牌并简单地委托给realm
4、认证策略
如果有多个Realm身份认证,通过认证策略来决定如何认证
5、Realm认证
realm中有两个方法,这里是最终提供认证与授权的逻辑的地方
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username= (String) principalCollection.getPrimaryPrincipal();
//根据username取userId
Long id = service.selectId(username);
//根据userID取roleId
List<Long> rid = userRoleService.selectId(id);
//根据rid取role
Set<String>roleNamelist=new HashSet<String>();
//根据rid取resourceId
List<Long> reid=new ArrayList<Long>();
for (Long r:rid) {
Role role = roleService.selectById(r);
roleNamelist.add(role.getName());
List<Long> reid1 = roleResourceService.selectId(r);
for (Long rei: reid1) {
reid.add(rei);
}
}
//根据resourceID取resourceUrl
Set<String> setUrl=new HashSet<String>();
for (Long reid2:reid) {
String s = resourceService.selectUrlById(reid2);
if (s!=null){
setUrl.add(s);
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setRoles(roleNamelist);//添加角色
info.addStringPermissions(setUrl);//添加权限
return info;
}
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username= (String) authenticationToken.getPrincipal();
User user = service.selectOne(new EntityWrapper<User>(new User(username)));
return new SimpleAuthenticationInfo(user.getLogin_name(),user.getPassword(), ByteSource.Util.bytes(salt),getName());
}
}
spring-shiro配置模板
<?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.xsd">
<!--创建shiroFilter,shiro的核心-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--注入securityManager-->
<property name="securityManager" ref="securityManager"/>
<!--如果没有认证,自动跳转到该页面-->
<property name="loginUrl" value="/login"/>
<!--过滤链-->
<property name="filterChainDefinitions">
<value>
/login*=anon
/commons/**=anon
/front/**=anon
/static/**=anon
/** = user<!--authc要登陆才能用,user只要登录过就可以-->
</value>
</property>
</bean>
<!--配置WebSecurityManager-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--注入自定义的realm-->
<property name="realm" ref="userRealm"/>
<!--缓存-->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!--自定义reelm,用来认证和授权-->
<bean class="com.study.shiro.UserRealm" id="userRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
<property name="authenticationCachingEnabled" value="true"/>
<property name="authenticationCacheName" value="authenticationCache"/>
<property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<!--凭证匹配器,用来解密md5-->
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher" id="credentialsMatcher">
<property name="hashAlgorithmName" value="md5"/>
</bean>
<!--生命周期-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!--换村-->
<bean class="org.apache.shiro.cache.ehcache.EhCacheManager" id="cacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
<bean class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager" id="sessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
<!--设置全局会话超时时间 -->
<property name="globalSessionTimeout" value="#{30 * 60 * 1000}"/>
<!--URL上带sessionID 默认为true-->
<property name="sessionValidationSchedulerEnabled" value="false"/>
</bean>
<bean class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" id="sessionDAO">
<property name="activeSessionsCacheName" value="activeSessionCache"/>
</bean>
</beans>
在webxml里的配置
<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>
网友评论