ssm及springboot整合shiro

目录

1.shiro的底层原理分析

1.1认证原理

1.2 授权原理

 1.3 授权方式

1.4 shiro过滤器

2.Realm对应操作

2.1 自定义Realm认证

2.2 加密

2.3 shiro使用密码加密器

2.3.1 测试类

2.3.2 修改realm代码

2.3.3 对应service

2.4 自定义realm的授权功能

2.4.1 授权功能

2.4.2 测试类

2.4.3 对应service类

2.4.4 实体类

3.ssm整合shiro

3.1 引入shiro的依赖

3.2  修改spring.xml配置文件

3.3 修改web.xml文件

3.4 权限问题

  3.4.1 拦截器

3.4.2 spring整合shiro时提供了一个注解

​编辑 3.4.3 全局变量

4.ssm整合shiro完成前后端分离

4.1 登录成功或者失败应该返回json数据

4.2 当未登录时返回的也是json数据

 4.3 如果没有权限应该返回json数据

5.关于ssm,shiro整合的例子

5.1 整体框架了解

5.2 controller层

5.2.1 LoginController

5.2.2 PerController

5.3 dao包

5.3.1 LoginMapper

        5.4 entity类

5.4.1 User

5.5 filter

5.5.1 LoginFilter

5.6 handle

5.6.1 MyException

5.7 realm

5.7.1 MyRealm

5.8 service

5.8.1 LoginService

5.8.2 LoginServiceImpl

5.9 util

5.9.1 CommonResult

5.10 mapper

5.10.1 loginMapper.xml

5.11 spring.xml

5.12 web.xml

5.13 依赖

6.springBoot整合shiro

6.1 依赖

6.2 application配置文件

6.3 创建shiro配置类

6.4 创建controller service dao entity(与ssm一致)

6.5 创建realm

 6.6 使用swagger进行登录测试和权限测试

6.6.1 引入swigger依赖

6.6.2 配置swigger

6.6.3 释放swigger资源

6.6.4 开启swigger注解

6.6.5 测试


1.shiro的底层原理分析

1.1认证原理

ssm及springboot整合shiro_第1张图片

(1)通过ini配置文件创建securityManager

(2)调用subject.login方法主体提交认证,提交的token

(3)securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。

(4)ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息

(5)IniRealm根据输入的token(UsernamePasswordToken,即这里的token是用户从页面输入的信息)从 shiro-first.ini查询用户信息(这里是测试阶段,后面都是查询的数据库,注入service,调用dao),根据账号查询用户信息(账号和密码)

         如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)

         如果查询不到,就给ModularRealmAuthenticator返回null

(6)ModularRealmAuthenticator接收IniRealm返回Authentication认证信息

         如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)

         如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)

小结

        ModularRealmAuthenticator作用进行认证,需要调用realm查询用户信息(在数据库中存在用户信息)

        ModularRealmAuthenticator进行密码对比(认证过程)。  

        realm:需要根据token中的身份信息去查询数据库(入门程序使用ini配置文件),如果查到用户返回认证信息,如果查询不到返回null。

1.2 授权原理

ssm及springboot整合shiro_第2张图片

(1)对subject进行授权,调用方法isPermitted("permission串")

(2)SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

(3)ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据

         调用realm的授权方法:doGetAuthorizationInfo

(4)realm从数据库查询权限数据,返回ModularRealmAuthorizer

(5)ModularRealmAuthorizer调用PermissionResolver进行权限串比对

(6)如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

 1.3 授权方式

有三种方式:

(1) 编程式:通过写if/else 授权代码块完成:(这种比较少用,一般在项目中采用后两种)

Subject subject = SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有权限

} else {

//无权限

}

(2) 注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresPermissions(value = {"user:query"},logical = Logical.OR)//使用shiro注解
    public String query(){
        return "user:query";
    }

(3) JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:

        在jsp页面导入shiro的标签既可以使用shiro的标签来进行权限的判断:

        Jsp页面添加:

<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>

1.4 shiro过滤器

过滤器简称 对应的java类 描述
anon org.apache.shiro.web.filter.authc.AnonymousFilter 匿名过滤器
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 如果继续操作,需要做出对应的表单验证否则不能通过

authcBasic

org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter

基本http验证过滤,如果不通过跳转至登录页面
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter 权限过滤器
port org.apache.shiro.web.filter.authz.PortFilter 端口过滤器可以设置是否是指向端口,如果不是跳转到登录页面
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter Http方法过滤器,可以指定如post的不能进行访问等
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter 角色过滤器判断,当前用户是否指定角色
ssl org.apache.shiro.web.filter.authz.SslFilter 请求需要通过ssl,如果不是跳转回登录页面
user org.apache.shiro.web.filter.authc.UserFilter 如果访问一个已知用户,比如记住我功能,然后走这个过滤器
logout org.apache.shiro.web.filter.authc.LogoutFilter 登录退出过滤器

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

 authc:/admins/user/**=authc,没有参数,表示需要认证(登录)才能使用,FormAuthenticationFilter是表单认证,通过记住我认证通过的不可以访问;

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

 user:/admins/user/**=user,没有参数,表示必须存在用户, 身份认证通过或通过记住我认证通过的可以访问,当登入操作时不做检查;

 logout:/logout=logout,没有参数,表示退出登录,清楚session。

2.Realm对应操作

        通过分析源码 ,最终认证交于realm完成认证功能,返回一个info, 如果info不为null,则进行密码比对。如果希望用数据库中的账号和密码完成认证功能,则只需要我们自定义一个类并继承AuthenticatingRealm。

2.1 自定义Realm认证

public class MyRealm extends AuthenticatingRealm {
    private UserService userService=new UserService();
    //该方法用于完成认证的功能
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.根据token获取账号
        String username = (String) authenticationToken.getPrincipal();
        //2.根据账号查询用户信息
        User user = userService.findByUsername(username);
        if(user!=null){
            //从数据库中获取的密码
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
            return info;
        }
        return null;
    }
}

2.2 加密

        shiro它提供了很多中加密器。其中使用最多就是HashedCredentialsMatcher。它的底层使用的是Md5加密。了解一下MD5加密:

public class Test03 {
    public static void main(String[] args) {
        //source:需要加密的明文
        Md5Hash md5Hash = new Md5Hash("123456");
        System.out.println(md5Hash);//e10adc3949ba59abbe56e057f20f883e密文---默认md5加密是不可逆的。但是网上由一些破解软件

        //salt:盐
        Md5Hash md5Hash1=new Md5Hash("123456","abc?!");
        System.out.println(md5Hash1);

        //设置n次加密
        Md5Hash md5Hash2 = new Md5Hash("123456","abc?!",1024);

    }
}

2.3 shiro使用密码加密器

2.3.1 测试类

public class Test01 {
    public static void main(String[] args) {
        //1.获取SecurityManager对象
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
//        //2.读取ini文件
//        IniRealm iniRealm=new IniRealm("classpath:shiro.ini");

        //创建Realm对象
        MyRealm myRealm=new MyRealm();

        //为realm指定加密器
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");//指定加密算法
        credentialsMatcher.setHashIterations(1024);//加密次数
        myRealm.setCredentialsMatcher(credentialsMatcher);

        //3。设置securityManager的realm
        securityManager.setRealm(myRealm);
        //4.设置securityManager上下文生效
        SecurityUtils.setSecurityManager(securityManager);

        //5.获取subject的主体对象
        Subject subject=SecurityUtils.getSubject();
        try{
            //UsernamePasswordToken作用是封装你输入的账号和密码 是客户自己输入的 用来进行比较与realm
            UsernamePasswordToken token=new UsernamePasswordToken("hh","123456");
            //抛出异常 比对shiro中realm和自己的对比,如果一致则登录成功,不一致则登录失败
            subject.login(token);
            System.out.println("登陆成功");
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("登陆失败");
        }
    }
}

2.3.2 修改realm代码

public class MyRealm extends AuthenticatingRealm {
    private UserService userService=new UserService();
    //该方法用于完成认证的功能
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //根据token获取账号
        String username = (String) authenticationToken.getPrincipal();
        //根据账号查询用户信息
        User user=userService.findByUsername(username);
        if(user!=null){
            ByteSource credentialsSat = ByteSource.Util.bytes(user.getSalt());
            System.out.println(user.getSalt());
            //从数据库中获取的密码
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSat,this.getName());
            //注意返回信息,若没有则会报错
            return info;
        }
        return null;
    }
}

2.3.3 对应service

public class UserService {
    public User findByUsername(String username) {
        if("admin".equals(username)){
            return new User(1,username,"小馒头","e18be766ad36f52ea76b2b2c9ad04f8e","abc");
        }else if("wd".equals(username)){
            return  new User(2,username,"孟一","55c23df0ffd3d32d68e83d47f21f7002","efg");
        }
        return null;
    }
}

2.4 自定义realm的授权功能

2.4.1 授权功能

public class MyRealm extends AuthorizingRealm {

    private UserService userService = new UserService();
    //授权部分
    //什么时候执行该方法:当你进行权限校验时会执行该方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        //根据账号查询该用户具有哪些权限
        List list = userService.findPermissionByUsername(user.getName());
        if(list!=null&&list.size()>0){
            SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.addStringPermissions(list);
            return simpleAuthorizationInfo;
        }
        return null;
    }

    //认证部分
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //1.根据token获得账号
        String username = (String) authenticationToken.getPrincipal();
        //2.根据账号查看用户信息
        User user = userService.findByUsername(username);

        if(user!=null){
            //从数据获取的密码
            ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSalt,this.getName());
            return info;
        }
        return null;
    }
}

2.4.2 测试类

public class Test02 {
    public static void main(String[] args) {
        //1.获取SecurityManager对象
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
//        //2.读取ini文件
//        IniRealm iniRealm=new IniRealm("classpath:shiro.ini");

        //创建Realm对象
        MyRealm myRealm=new MyRealm();

        //为realm指定加密器
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");//指定加密算法
        credentialsMatcher.setHashIterations(1024);//加密次数
        myRealm.setCredentialsMatcher(credentialsMatcher);

        //3。设置securityManager的realm
        securityManager.setRealm(myRealm);
        //4.设置securityManager上下文生效
        SecurityUtils.setSecurityManager(securityManager);

        //5.获取subject的主体对象
        Subject subject=SecurityUtils.getSubject();
        try{
            //UsernamePasswordToken作用是封装你输入的账号和密码 是客户自己输入的 用来进行比较与realm
            UsernamePasswordToken token=new UsernamePasswordToken("wd","123456");
            //抛出异常 比对shiro中realm和自己的对比,如果一致则登录成功,不一致则登录失败
            subject.login(token);
            System.out.println(subject.isPermitted("user:query"));
            System.out.println(subject.isPermitted("user:update"));
        }catch(Exception e){
            System.out.println("登陆失败");
        }
    }
}

2.4.3 对应service类

public class UserService {
    public User findByUsername(String username) {
        if("admin".equals(username)){
            return new User(1,username,"小馒头","e18be766ad36f52ea76b2b2c9ad04f8e","abc");
        }else if("wd".equals(username)){
            return  new User(2,username,"孟一","55c23df0ffd3d32d68e83d47f21f7002","efg");
        }
        return null;
    }

    public List findPermissionByUsername(String username){
        List list=new ArrayList<>();
        if("admin".equals(username)){
            list.add("user:query");
            list.add("user:update");
            list.add("user:insert");
            list.add("user:delete");
        }else if("wd".equals(username)){
            list.add("user:query");
            list.add("user:insert");
        }
        return list;
    }
}

2.4.4 实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private String realname;
    private String password;
    private  String salt;

}

3.ssm整合shiro

(1)创建一个maven的web工程。

(2)ssm整合到web工程----省略

pom依赖

spring配置文件

web.xml配置文件

(3)整合shiro

3.1 引入shiro的依赖

    
   
      org.apache.shiro
      shiro-spring
      1.9.0
   

3.2  修改spring.xml配置文件




    
    
    
    
    
    

    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
    

    
    

        
        
        
    

    
    
        
    
    
    


    
    
    
        
    
    
    
        
    

    
    
        
        
    

    
    
    
    
        
    

    
    
        

        
            
                /login/upLogin=anon
                /**=authc
            
        
        
            
                
                    
                
            
        
    

3.3 修改web.xml文件




    
        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet

        
            contextConfigLocation
            classpath:spring.xml
        

        1
    

    
        dispatcherServlet
        /
    

    
        encodeFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
        
            forceRequestEncoding
            true
        
        
            forceResponseEncoding
            true
        
    

    
        encodeFilter
        /*
    

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

    
        shiroFilter
        /*
    







3.4 权限问题

进入主页后,不同的用户可以看到不同的内容

ssm及springboot整合shiro_第3张图片

 可以在jsp中获取当前登录者的账号

上面只是在网页中根据不同用户显示不同的菜单,这种方式只能防君子不能防小人。

  3.4.1 拦截器

获取请求路径 然后根据你的路径判断当前用户是否具有该权限。

public class LoginFilter extends FormAuthenticationFilter {
    //当没有登录时会经过该方法。如果想让他返回json数据那么必须重写该方法

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer=response.getWriter();
        CommonResult commonResult=new CommonResult(4001,"未登录",null);
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        writer.print(json);//响应给客户json数据
        writer.flush();
        writer.close();
        return false;
    }
}

3.4.2 spring整合shiro时提供了一个注解

可以加载相应方法上

1.开启shiro注解

              class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
                class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
            depends-on="lifecycleBeanPostProcessor" />
                class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
       
   

    
2.使用shiro注解
  @RequiresPermissions(value = {"/user/query","/user/aaa"},logical= Logical.OR)

ssm及springboot整合shiro_第4张图片 3.4.3 全局变量

@ControllerAdvice
public class MyException {
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public CommonResult auth(UnauthorizedException e){
        e.printStackTrace();
        return new CommonResult(4002,"权限不足",null);
    }
}

4.ssm整合shiro完成前后端分离

        所谓前后端完全分离:后端响应的都是json数据,而不再是网页。

1. 登录成功或者失败应该返回json数据
2. 当未登录时返回的也是json数据
3. 访问未授权的资源,也要分会json。

4.1 登录成功或者失败应该返回json数据

修改登录接口

ssm及springboot整合shiro_第5张图片

 

4.2 当未登录时返回的也是json数据

创建一个过滤器,继承登录校验的某个接口。

public class LoginFilter extends FormAuthenticationFilter {
    //当没有登录时会经过该方法。如果想让他返回json数据那么必须重写该方法

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer=response.getWriter();
        CommonResult commonResult=new CommonResult(4001,"未登录",null);
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        writer.print(json);//响应给客户json数据
        writer.flush();
        writer.close();
        return false;
    }
}

注册过滤器 :注意路径

ssm及springboot整合shiro_第6张图片

 4.3 如果没有权限应该返回json数据

ssm及springboot整合shiro_第7张图片

5.关于ssm,shiro整合的例子

5.1 整体框架了解

ssm及springboot整合shiro_第8张图片ssm及springboot整合shiro_第9张图片

5.2 controller层

5.2.1 LoginController

@RestController
@RequestMapping("/login")
public class LoginController {
    @Autowired
    private LoginService loginService;

    @GetMapping("/upLogin")
    public CommonResult upLogin(String username,String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);
        try{
            subject.login(token);
            return new CommonResult(200,"登陆成功",null);
        }catch (Exception e){
            e.printStackTrace();
            return new CommonResult(500,"登陆失败",null);
        }

    }
}

5.2.2 PerController

@RestController
@RequestMapping("/permission")
public class PerController {
    //默认spring框架不识别该注解。需要springmvc配置文件中开启该注解
    @GetMapping("/query")
    @RequiresPermissions(value = {"user:query"},logical = Logical.OR)//使用shiro注解,此处user:query与数据库形式一致
    public String query(){
        return "user:query";
    }

    @GetMapping("/update")
    @RequiresPermissions(value = {"user:update"})
    public String update(){
        return "user:update";
    }

    @GetMapping("/insert")
    @RequiresPermissions(value = {"user:insert"})
    public String insert(){
        return "user:insert";
    }

    @GetMapping("/delete")
    @RequiresPermissions(value = {"user:delete"})
    public String delete(){
        return "user:delete";
    }

    @GetMapping("/export")
    @RequiresPermissions(value = {"user:export"})
    public String export(){
        return "user:export";
    }
}

5.3 dao包

5.3.1 LoginMapper

public interface LoginMapper {

    public User findByName(String username);

    public List findPrimaryById(Integer userid);
}

5.4 entity类

5.4.1 User

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer userid;

    private String username;

    private String userpwd;

    private String sex;

    private String address;

    private String salt;
}

5.5 filter

5.5.1 LoginFilter

public class LoginFilter extends FormAuthenticationFilter {
    //当没有登录时会经过该方法。如果想让他返回json数据那么必须重写该方法

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer=response.getWriter();
        CommonResult commonResult=new CommonResult(4001,"未登录",null);
        ObjectMapper objectMapper=new ObjectMapper();
        String json = objectMapper.writeValueAsString(commonResult);
        writer.print(json);//响应给客户json数据
        writer.flush();
        writer.close();
        return false;
    }
}

5.6 handle

5.6.1 MyException

@ControllerAdvice
public class MyException {
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseBody
    public CommonResult auth(UnauthorizedException e){
        e.printStackTrace();
        return new CommonResult(4002,"权限不足",null);
    }
}

5.7 realm

5.7.1 MyRealm

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private LoginService loginService;
    //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        //根据该账号查询用户有哪些权限
        List primary = loginService.findPrimaryById(user.getUserid());
        System.out.println(primary);
        if(primary!=null&&primary.size()>0){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            info.addStringPermissions(primary);
            return info;
        }
        return null;
    }
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        String  user = (String) authenticationToken.getPrincipal();
        User byName = loginService.findByName(user);
        if(byName!=null){
            ByteSource source = ByteSource.Util.bytes(byName.getSalt());
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(byName,byName.getUserpwd(),source,this.getName());
            return info;
        }

        return null;
    }
}

5.8 service

5.8.1 LoginService

public interface LoginService {

    public User findByName(String username);

    public List findPrimaryById(Integer userid);
}

5.8.2 LoginServiceImpl

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private LoginMapper loginMapper;

    public User findByName(String username) {
        User name = loginMapper.findByName(username);
        return name;
    }

    public List findPrimaryById(Integer userid) {
        List list = loginMapper.findPrimaryById(userid);
        return list;
    }
}

5.9 util

5.9.1 CommonResult

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult {
    private Integer code;
    private String msg;
    private Object data;
}

5.10 mapper

5.10.1 loginMapper.xml




    
        userid,username,userpwd,sex,address,salt
    
    

    
        update user
            
                
                    username=#{username},
                
                
                    userpwd=#{userpwd},
                
                
                    sex=#{sex},
                
                
                    address=#{address},
                
                
                    salt=#{salt},
                
            
            where userid=#{userid}
    

    
        insert into user(userid,username,userpwd,sex,address,salt)
            values (null,#{username},#{userpwd},#{sex},#{address},#{salt})
    

    
        delete from user where userid=#{userid}
    

    

5.11 spring.xml




    
    
    
    
    
    

    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
    

    
    

        
        
        
    

    
    
        
    
    
    


    
    
    
        
    
    
    
        
    

    
    
        
        
    

    
    
    
    
        
    

    
    
        

        
            
                /login/upLogin=anon
                /**=authc
            
        
        
            
                
                    
                
            
        
    

5.12 web.xml




    
        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet

        
            contextConfigLocation
            classpath:spring.xml
        

        1
    

    
        dispatcherServlet
        /
    

    
        encodeFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
        
            forceRequestEncoding
            true
        
        
            forceResponseEncoding
            true
        
    

    
        encodeFilter
        /*
    

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

    
        shiroFilter
        /*
    








5.13 依赖

 
    
    
      org.springframework
      spring-webmvc
      5.2.15.RELEASE
    

    
    
      org.mybatis
      mybatis
      3.5.6
    

    
    
      org.mybatis
      mybatis-spring
      2.0.6
    

    
    
      mysql
      mysql-connector-java
      8.0.28
    

    
    
      com.alibaba
      druid
      1.2.1
    

    
    
      org.projectlombok
      lombok
      1.18.24
    

    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.13.2.2
    

    
    
      javax.servlet
      javax.servlet-api
      4.0.1
    

    
      org.springframework
      spring-jdbc
      5.2.15.RELEASE
    
    
      org.springframework
      spring-tx
      5.2.15.RELEASE
    
    
      org.springframework
      spring-aspects
      5.2.15.RELEASE
    
    
    
      org.mybatis.generator
      mybatis-generator-core
      1.4.0
    


    
      log4j
      log4j
      1.2.17
    


    
    
      org.apache.shiro
      shiro-spring
      1.9.0
    



  

6.springBoot整合shiro

6.1 依赖



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.3.12.RELEASE
         
    
    com.qy151wd
    springboot_shiro
    0.0.1-SNAPSHOT
    springboot_shiro
    Demo project for Spring Boot
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.projectlombok
            lombok
            true
        

        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.1
        

        
            org.apache.shiro
            shiro-spring-boot-starter
            1.7.0
        


        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            com.spring4all
            swagger-spring-boot-starter
            1.9.1.RELEASE
        
        
            com.github.xiaoymin
            swagger-bootstrap-ui
            1.7.8
        

    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    


6.2 application配置文件

#数据源
spring.datasource.url=jdbc:mysql://localhost:3306/project?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#端口号
server.port=8808

#sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

6.3 创建shiro配置类

@Configuration
public class ShiroConfig {
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(realm());
        return securityManager;

    }

    @Bean
    public Realm realm(){
        MyRealm myRealm=new MyRealm();
        myRealm.setCredentialsMatcher(credentialsMatcher());
        return myRealm;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher=new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName("MD5");
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

    @Bean(value = "shiroFilter")
    public ShiroFilterFactoryBean filterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());

        //设置拦截规则
        HashMap map=new HashMap<>();
        map.put("/login/upLogin","anon");
        map.put("/**/*.css","anon");
        map.put("/**/*.js","anon");
        map.put("/doc.html","anon");
        map.put("/swagger-resources","anon");
        map.put("/v2/api-docs","anon");
        map.put("/**","authc");
        factoryBean.setFilterChainDefinitionMap(map);

        //设置自定义认证过滤器
        HashMap filterMap=new HashMap();
        filterMap.put("authc",new LoginFilter());
        factoryBean.setFilters(filterMap);

        return factoryBean;
    }

    @Bean //注册filter
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setName("shiroFilter");
        filterRegistrationBean.setFilter(new DelegatingFilterProxy());
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    //开始shiro注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}

注意: (此处不进行修改会报错)

ssm及springboot整合shiro_第10张图片

6.4 创建controller service dao entity(与ssm一致)

6.5 创建realm

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private LoginService loginService;
    //授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        //根据该账号查询用户有哪些权限
        List primary = loginService.findPrimaryById(user.getUserid());
        System.out.println(primary);
        if(primary!=null&&primary.size()>0){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            info.addStringPermissions(primary);
            return info;
        }
        return null;
    }
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        String  user = (String) authenticationToken.getPrincipal();
        User byName = loginService.findByName(user);
        if(byName!=null){
            ByteSource source = ByteSource.Util.bytes(byName.getSalt());
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(byName,byName.getUserpwd(),source,this.getName());
            return info;
        }

        return null;
    }
}

开启shiro注解  

//开始shiro注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

 6.6 使用swagger进行登录测试和权限测试

doc.html无法访问以及样式无效。 shiro拦截规则拦截了 .

6.6.1 引入swigger依赖

上边所给的依赖已经引入



    com.spring4all
    swagger-spring-boot-starter
    1.9.1.RELEASE


    com.github.xiaoymin
    swagger-bootstrap-ui
    1.7.8

6.6.2 配置swigger

@Configuration
public class SwaggerConfig {
    @Bean//swagger中所有的功能都封装在Docket类中
    public Docket docket(){
        Docket docket=new Docket(DocumentationType.SWAGGER_2)
                .host("localhost:8808")
                .apiInfo(apiInfo())//设置api文档信息
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.qy151wd.controller"))
                .build();

        return docket;
    }


    //定义自己接口文档信息
    private ApiInfo apiInfo(){
        Contact DEFAULT_CONTACT = new Contact("小可", "http://www.baidu.com", "[email protected]");
        ApiInfo apiInfo = new ApiInfo("萌萌的小项目", "适合小新手", "V1.0", "http://www.jd.com",
                DEFAULT_CONTACT, "牛牛公司", "http://www.taobao.com", new ArrayList());
        return apiInfo;
    }
}

6.6.3 释放swigger资源

上述配置shiro也已经释放此处的静态swigger资源

ssm及springboot整合shiro_第11张图片

6.6.4 开启swigger注解

ssm及springboot整合shiro_第12张图片

 6.6.5 测试

在页面上输入localhost:对应端口号/doc.html,可直接查看,结果为

ssm及springboot整合shiro_第13张图片

 

你可能感兴趣的:(java高级,spring,boot,java,spring)