写在前面
1、Shiro是Apache下的一个开源项目,我们称之为Apache Shiro。它是一个很易用与Java项目的的安全框架,提供了认证、授权、加密、会话管理,与spring Security 一样都是做一个权限的安全框架,但是与Spring Security 相比,在于 Shiro 使用了比较简单易懂易于使用的授权方式。shiro属于轻量级框架,相对于security简单的多,也没有security那么复杂。所以我这里也是简单介绍一下shiro的使用。
2、非常简单;其基本功能点如下图所示:
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
记住一点,Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。
配置
1 maven 配置
4.0.0 com.troy springshiro 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 1.5.6.RELEASE org.springframework.boot spring-boot-starter-web 1.5.6.RELEASE org.springframework.boot spring-boot-starter-data-jpa 1.5.6.RELEASE org.springframework.boot spring-boot-autoconfigure 1.5.6.RELEASE mysql mysql-connector-Java 5.1.9 org.apache.shiro shiro-spring 1.3.2 com.alibaba druid 1.1.4
2 自定义Realm配置
//实现AuthorizingRealm接口用户用户认证public class MyShiroRealm extends AuthorizingRealm{ //用于用户查询 @Autowired private ILoginService loginService; //角色权限和对应权限添加 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取登录用户名 String name= (String) principalCollection.getPrimaryPrincipal(); //查询用户名称 User user = loginService.findByName(name); //添加角色和权限 SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (Role role:user.getRoles()) { //添加角色 simpleAuthorizationInfo.addRole(role.getRoleName()); for (Permission permission:role.getPermissions()) { //添加权限 simpleAuthorizationInfo.addStringPermission(permission.getPermission()); } } return simpleAuthorizationInfo; } //用户认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //加这一步的目的是在Post请求的时候会先进认证,然后在到请求 if (authenticationToken.getPrincipal() == null) { return null; } //获取用户信息 String name = authenticationToken.getPrincipal().toString(); User user = loginService.findByName(name); if (user == null) { //这里返回后会报出对应异常 return null; } else { //这里验证authenticationToken和simpleAuthenticationInfo的信息 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName()); return simpleAuthenticationInfo; } }}
3 shiro Configuration 配置
@Configurationpublic class ShiroConfiguration { //将自己的验证方式加入容器 @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } //权限管理,配置主要是Realm的管理认证 @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } //Filter工厂,设置对应的过滤条件和跳转条件 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Mapmap = new HashMap (); //登出 map.put("/logout","logout"); //对所有用户认证 map.put("/**","authc"); //登录 shiroFilterFactoryBean.setLoginUrl("/login"); //首页 shiroFilterFactoryBean.setSuccessUrl("/index"); //错误页面,认证不通过跳转 shiroFilterFactoryBean.setUnauthorizedUrl("/error"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } //加入注解的使用,不加入这个注解不生效 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }}
4 自定义authc 配置
/** */package com.tools.shiro;import java.io.IOException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletResponse;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;import org.springframework.stereotype.Component;/** * @author * * shiro 自定义拦截器配置 */@Component(value = "stateless")public class StatelessAuthcFilter extends FormAuthenticationFilter { public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { return super.onPreHandle(request, response, mappedValue); } @SuppressWarnings("unused") private void doNoAuthc(ServletResponse response) throws IOException { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } @SuppressWarnings("unused") private void doFail(ServletResponse response) throws IOException { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); }}