shiro---spring boot整合

shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证、用户授权。

spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。

shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,越来越多企业项目开始使用shiro。

使用shiro实现系统 的权限管理,有效提高开发效率,从而降低开发成本。

subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。

securityManager:安全管理器,主体进行认证和授权都 是通过securityManager进行。

authenticator:认证器,主体进行认证最终通过authenticator进行的。

authorizer:授权器,主体进行授权最终通过authorizer进行的。

sessionManager:web应用中一般是用web容器对session进行管理,shiro也提供一套session管理的方式。

SessionDao:  通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao。

cache Manager:缓存管理器,主要对session和授权数据进行缓存,比如将授权数据通过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。

realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据。

cryptography:密码管理,提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。

比如 md5散列算法。

pom.xml

<properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- shiro加入注解时要加入的包 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.1</version>
        </dependency>
        <!-- shiro缓存 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 缓存ehcache -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.8.1</version>
        </dependency>

    </dependencies>

//spring boot Realm 用于认证和授权
@Component
public class CustomRealm extends AuthorizingRealm {
  //注入service
@Autowired
UserService userService;
@Override
  //认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String username = (String) authenticationToken.getPrincipal();

String password = userService.queryPasswordByName(username);
   
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, "customRealm");

return info;
}

@Override
  //授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//根据认证传进来的user信息 查询该user所对应的perms信息
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();

List<String> perms = userService.queryPermsByName(primaryPrincipal);

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

info.addStringPermissions(perms);

return info;
}


}

//spring boot Configuration Shiro配置
@Configuration
public class ShiroConfig {

    /*注册realm 注册sessionManager*/
    /*注册cacheManager*/
    @Bean
    public SecurityManager securityManager(CustomRealm customRealm,
                                           DefaultWebSessionManager sessionManager,
                                           EhCacheManager ehCacheManager){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(customRealm);
        defaultWebSecurityManager.setSessionManager(sessionManager);
        defaultWebSecurityManager.setCacheManager(ehCacheManager);
        return defaultWebSecurityManager;
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unAuthor");
        HashMap<String, String> filterMap = new HashMap<>();
        filterMap.put("/unAuthor","anon");
        filterMap.put("/login","anon");
        filterMap.put("/refuse","anon");
        //filterMap.put("/admin/user/*","perms[user:query]");
        filterMap.put("/logout","logout");
        filterMap.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }
   //加入注解的方式
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

   //失败页面
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();

        properties.setProperty("org.apache.shiro.authz.UnauthorizedException","/refuse");

        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return simpleMappingExceptionResolver;

    }
    /*session Manager*/
    @Bean
    public DefaultWebSessionManager defaultWebSessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(60000);
        sessionManager.setDeleteInvalidSessions(true);
        return sessionManager;
    }
    /*注册cacheManager*/
    @Bean
    public EhCacheManager ehCacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:shiro-cache.xml");
        return ehCacheManager;
    }
}

//shiro-cache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!--diskStore:缓存数据持久化的目录 地址  -->
    <diskStore path="E:\develop\ehcache" />
    <defaultCache
            maxElementsInMemory="1000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            diskPersistent="false"
            timeToIdleSeconds="10"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

//controller
@RequestMapping("login")
public String login(String username,String password){
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);

}catch (Exception i){
return "login";
}

return "success";
}
 
/*简单说明

<defaultCache

            maxElementsInMemory="10000"

内存中缓存的最大的对象条目

            eternal="false"

是否放在磁盘

            timeToIdleSeconds="120

对象的空闲时间 单位是s 超时即从内存去掉

            timeToLiveSeconds="120"

对象的生存周期 单位是s  2min

            overflowToDisk="true"

内存中超过上限之后否放在磁盘中

            maxElementsOnDisk="10000000"

disk中最多保存多少个对象

            diskPersistent="false"

jvm 终止的时候是否保存到磁盘中

            diskExpiryThreadIntervalSeconds="120"

120s 轮询一次,去清除过期的对象

            memoryStoreEvictionPolicy="LRU"

内存清除策略:LRU 把某些cache干掉

Least Recently Used 算法 最近最少使用算法

去最近的一段时间内最不经常使用的那些对象。

LFU least Frequency Used  最不经常使用

使用频率最小的那些对象

FIFO  fisrt in first out 队列   />

  • /*RequiresAuthentication:

使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。

  • RequiresGuest:

使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。

  • RequiresPermissions:

当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。

  • RequiresRoles:

当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。

  • RequiresUser

当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。

注意:

Shiro的认证注解处理是有内定的处理顺序的,如果有个多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关):

*/

猜你喜欢

转载自www.cnblogs.com/lianqiqi/p/11023894.html