shiro实现登录认证与权限授权管理

Apache Shiro 是一个强大而灵活的开源安全框架,从官网上,我们基本上可以了解到,她提供的服务非常明确:
1.Authentication(认证)

2.Authorization(授权)

3.Session Management(会话管理)

4.Cryptography(加密)

1.maven配置

        
        
            org.apache.shiro
            shiro-all
            1.4.0
        
        
            org.apache.shiro
            shiro-cas
            1.2.0
        

2 在web.xml中添加shiro过滤器

 
    
      
        
        shiroFilter
        org.springframework.web.filter.DelegatingFilterProxy
        
            targetFilterLifecycle
            true
        
    

3 spring中对shiro配置



    
    
        
    
    
        
    

    
    
        
        
        
        
        
        
        
        
        
            
                
                
            
        
        
        
            
                /checkpreload.htm = anon 
                /agent.ateye = anon
                /agent.jveye = anon
                / = authc
                /login/callback.htm = anon
                /login/login.htm = anon
                /login/checkLogin.htm = anon
                /login/unauthorized.htm = anon
                /login/changeSeller.htm = authc
                /login/logout = logout
                /login/api/** = anon
                /login/** = anon
                /** = authc
            
        
    
    
    
        
        
    

    
    

    
    
        
        
        
        
        
        
    
	
    
      
    

    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
    
    
    

    
    
        
        
        
        
        
        
    

    
    
        
        
        
        
    

    
    
    


property name="filters"可以配置我们自定义的filter
shiron自带的filter如下我们可以继承这些filter来实现自己需要的一些功能,这些filter也就是filterChainDefinitions过滤规则所执行的filter我们可以根据过滤条件选择我们需要继承的filter

Filter Name Class 含义
anon org.apache.shiro.web.filter.authc.AnonymousFilter 没有参数,表示可以匿名使用。
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 表示需要认证(登录)才能使用,没有参数
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter 没有参数表示httpBasic认证
logout org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation org.apache.shiro.web.filter.session.NoSessionCreationFilter
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms[“user:add:,user:modify:”],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
port org.apache.shiro.web.filter.authz.PortFilter 当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles[“admin,guest”],每个参数通过才算通过,相当于hasAllRoles()方法。
ssl org.apache.shiro.web.filter.authz.SslFilter 表示安全的url请求,协议为https
user org.apache.shiro.web.filter.authc.UserFilter 没有参数表示必须存在用户,当登入操作时不做检查

cacheManager和sessionDAO的区别:
cacheManager缓存里可以包含权限认证的缓存、用户及权限信息的缓存等,也可以做session缓存。但是sessionDAO顾名思义就是做session持久化的,只是它刚好可以使用redis来存储而已。是完全不同的两个概念,通俗来说cacheManager是用来存储用户信息的sessionDAO是用来做session缓存的。

4 自定义Shiro缓存管理器

public class ShiroRedisCacheManager implements CacheManager, Initializable, Destroyable {


    private String keyPrefix = "shiro_redis_cache:";
    //ShiroRedisManager 为redis工具类
    private ShiroRedisManager redisManager;
    @Override
    public  Cache getCache(String name) throws CacheException {
       //RedisCache为Cache 实现类 实现类方法内通过redisManager进行数据操作
        Cache c  = new RedisCache(redisManager, keyPrefix);

        return c;
    }
}

实现CacheManager接口就可以了

4.getSessionId的重写

/** * Description:shiro框架 自定义session获取方式 *
可自定义session获取规则。这里采用ajax请求头authToken携带sessionId的方式 * **/ public
class ShiroSessionManager extends DefaultWebSessionManager {

private static final String AUTHORIZATION = "authToken";

private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";

public ShiroSessionManager(){
    super();
}

@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response){
    String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
    System.out.println("id:"+id);
    if(StringUtils.isEmpty(id)){
        //如果没有携带id参数则按照父类的方式在cookie进行获取
        System.out.println("super:"+super.getSessionId(request, response));
        return super.getSessionId(request, response);
    }else{
        //如果请求头中有 authToken 则其值为sessionId    request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,REFERENCED_SESSION_ID_SOURCE);
        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,id);
        request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
        return id;
    }
}

5 自定义Realm编码

public class OauthRealm extends AuthorizingRealm {
	// 设置realm的名称
	@Override
	public void setName(String name) {
		super.setName("customRealm");
	}
 
	@Autowired
	private AdminUserService adminUserService;
 
	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
 
		// token中包含用户输入的用户名和密码
		// 第一步从token中取出用户名
		String userName = (String) token.getPrincipal();
		// 第二步:根据用户输入的userCode从数据库查询
		TAdminUser adminUser = adminUserService.getAdminUserByUserName(userName);
		// 如果查询不到返回null
		if (adminUser == null) {//
			return null;
		}
		// 获取数据库中的密码
		String password = adminUser.getPassword();
		/**
		 * 认证的用户,正确的密码
		 */
 
		return SimpleAuthenticationInfo(adminUser, token.getCredentials(), getName());
	}
 
	/**
	 * 授权,只有成功通过doGetAuthenticationInfo方法的认证后才会执行。
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
	SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 从 principals获取主身份信息
		// 将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
		TAdminUser activeUser = (TAdminUser)SecurityUtils.getSubject().getPrincipal();
		// 根据身份信息获取权限信息
		// 从数据库获取到角色数据
		TAdminRole roles= adminUserService.getAdminRoles(activeUser);
		//遍历角色下的功能位
		for (RoleDO role : roles) {
        Set permissionList = new HashSet<>();
        List functionBits = role.getFunctionBitList();
        for (int i = 0; i < functionBits.size(); i++) {
            permissionList.add(functionBits.get(i) + "");
        }
         //将功能位列表就是最终的权限 通过在控制层@RequiresPermissions("3")注解限制权限为3才可以访问
        info.addStringPermissions(permissionList);
    }
		return simpleAuthorizationInfo;

你可能感兴趣的:(架构)