1, 什么是Shiro

  Shiro是一个安全框架,用于解决系统的认证和授权问题,同时提供了会话管理,数据加密,与WEB集成,缓存等机制。

Authentication身份认证/登录,验证用户是不是拥有相应的身份;

Authorization授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

2、传统认证与Shiro的对比。

  传统的认证,在controller层,自己编写相应的业务层与doa层方法获取数据库存储的数据进行验证

  shiro、需要在shiro的realm中配置好,保存真实的数据源的地址,以及验证的方式(   ....)。在controller与shiro进行交互

3,Shiro的架构

Subject主体,可以看到主体可以是任何可以与应用交互的“用户”; 这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫等;即一个抽象概念;

SecurityManagerShiro的核心控制器,相当于SpringMVC中的DispatcherServlet;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会话、缓存的管理。

Authenticator认证器,负责主体认证。

Authrizer授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;

Realm域,Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

SessionManager管理Session生命周期的组件;Shiro并不仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境;因此Shiro抽象了一个SessionManager来管理主体与应用之间交互的数据;

 SessionDAO用来将Session保存到数据库,可以实现自己的SessionDAO,通过如JDBC写到数据库;或者把Session放到Memcached中,可以实现自己的Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;

CacheManager缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能

Cryptography密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

4,Shiro与应用程序的交互过程

1)应用代码通过Subject来进行认证和授权,而Subject又委托给SecurityManager;

2)我们需要给Shiro的SecurityManager注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。

5,shiro认证

6. Shiro授权:

授权,也叫访问控制,即在应用中控制谁能访问哪些资源

7.Shiro加密

    Shior散列HashedCredentialsMatcher密码匹配器

    自定义Realm中使用盐值加密

8.Web集成:

a)  Shiro提供了与Web集成的支持,其通过一个ShiroFilter入口来拦截需要安全控制的URL,ShiroFilter类似于如Strut2/SpringMVC这种web框架的前端控制器,是安全控制的入口点,负责读取配置(如ini配置文件),然后判断URL是否需要登录/权限等工作

b)  org.springfraemwork.web.filter.DelegatingFilterProxy

rest例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。

port例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString

是你访问的url里的?后面的参数。

perms例子/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于

isPermitedAll()方法。

roles例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

anon例子/admins/**=anon 没有参数,表示可以匿名使用。

authc例如/admins/user/**=authc表示需要认证才能使用,没有参数

authcBasic例如/admins/user/**=authcBasic没有参数表示httpBasic认证

ssl例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https

user例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查

其中anon,authcBasic,auchc,user是是认证过滤器,perms,roles,ssl,rest,port授权过滤器。

9.集成spring

A,配置过滤器,在webapp.xml中

<filter>
  <filter-name>shiroFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>shiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

B,spring配置,参照shiro第二斩

<!--shiro配置-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="loginUrl" value="login.html"></property>
    <property name="securityManager" ref="securityManager"></property>
    <property name="unauthorizedUrl" value="403.html"></property>
    <property name="successUrl" value="index"></property>
    <property name="filterChainDefinitions">
        <value>
            /login.html = anon
            /doLogin = anon
            /* = authc
        </value>
    </property>
</bean>

 springboot配置。这个是自定义域。SSM与springboot一样的。注册的方式不同。这个要加入到securityManager中

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    @Autowired
    private FunctionService functionService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权");
        User user = (User)principalCollection.getPrimaryPrincipal();
        //从数据中获取角色权限数据
        User roleUser = userService.findUserRolePremissionsByUserCode(user.getUsercode());
        List<String> premissions = new ArrayList<>();
        List<String> roles = new ArrayList<>();
        roles.add(roleUser.getRole().getRolename());
        for(Function f :roleUser.getRole().getFunctions()){
            premissions.add(f.getFunctionname());
        }
       // List<String> list = functionService.getFunctionNameByUserCode(user.getUsercode());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(premissions);//权限
        info.addRoles(roles);//角色
        return info;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //从主体提交过来的认证信息中
        String userName = (String)authenticationToken.getPrincipal();
        //通过用户名到数据库中获取凭证
        User user = userService.getUserByName(userName);
        System.out.println(userName+"??");
        if(user == null){
            return null;
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getUserpassword(),this.getName());
        info.setCredentialsSalt(ByteSource.Util.bytes("hello"));
        return info;
    }

10.shiro标签

10.Shiro权限注解

     Shiro提供了相应的注解用于权限控制,如果使用这些注解就需要使用AOP的功能来进行判断,Shiro提供了Spring AOP集成用于权限注解的解析和验证。

  1) 在spring-mvc.xml配置文件添加Shiro Spring AOP权限注解的支持:

<aop:config proxy-target-class="true"></aop:config>
<bean class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean>  

  2) 配置依赖:

<dependency>
  <groupId>aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.5.0</version>
</dependency>

  3) 当验证失败,其会抛出UnauthorizedException异常,此时可以使用Spring的ExceptionHandler(DefaultExceptionHandler)来进行拦截处理:

@ExceptionHandler({UnauthorizedException.class})
public ModelAndView processUnauthenticatedException() {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("forward:/403.html");
    return mv;
}  

   4)注解

@RequiresAuthentication 表示当前Subject已经通过login进行了身份验证;即Subject. isAuthenticated()返回true。

@RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)  

表示当前Subject需要角色admin和user。

@RequiresPermissions (value={“user:update”, “user:delete”}, logical= Logical.OR)  

表示当前Subject需要权限user:update或user:delete 

SpringBoot集成Shiro

一. 配置依赖

二. Shiro配置

三. thymeleaf使用shiro

  1. 1.      配置依赖
    1. A.     <dependency>
    2. B.             <groupId>com.github.theborakompanioni</groupId>
    3. C.             <artifactId>thymeleaf-extras-shiro</artifactId>
    4. D.             <version>2.0.0</version>
    5. E.      </dependency>

 

  1. 2.      注册Bean
    1. A.     ShiroDialect
  2. 3.      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"

 

02-13 22:48