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

(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)对subject进行授权,调用方法isPermitted("permission串")
(2)SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
(3)ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据
调用realm的授权方法:doGetAuthorizationInfo
(4)realm从数据库查询权限数据,返回ModularRealmAuthorizer
(5)ModularRealmAuthorizer调用PermissionResolver进行权限串比对
(6)如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。
有三种方式:
(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" %>
| 过滤器简称 | 对应的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。
通过分析源码 ,最终认证交于realm完成认证功能,返回一个info, 如果info不为null,则进行密码比对。如果希望用数据库中的账号和密码完成认证功能,则只需要我们自定义一个类并继承AuthenticatingRealm。
- 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;
- }
- }
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);
-
- }
- }
- 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("登陆失败");
- }
- }
- }
- 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;
- }
- }
- 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 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;
- }
- }
- 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("登陆失败");
- }
- }
- }
- 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;
- }
- }
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class User {
- private Integer id;
- private String name;
- private String realname;
- private String password;
- private String salt;
-
- }
(1)创建一个maven的web工程。
(2)ssm整合到web工程----省略
pom依赖
spring配置文件
web.xml配置文件
(3)整合shiro
org.apache.shiro
shiro-spring
1.9.0
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
-
-
- <context:component-scan base-package="com.qy151wd.service,com.qy151wd.controller"/>
-
- <mvc:annotation-driven/>
-
- <mvc:default-servlet-handler/>
-
-
-
- <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
-
- <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/project?serverTimezone=Asia/Shanghai"/>
- <property name="username" value="root"/>
- <property name="password" value="123456"/>
-
- <property name="initialSize" value="5"/>
-
- <property name="minIdle" value="5"/>
-
- <property name="maxActive" value="10"/>
-
- <property name="maxWait" value="3000"/>
- bean>
-
-
- <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="ds"/>
-
- <property name="mapperLocations" value="classpath:mapper/*.xml"/>
- bean>
-
-
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
-
- <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
-
- <property name="basePackage" value="com.qy151wd.dao"/>
- bean>
-
-
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="ds"/>
- bean>
-
- <tx:annotation-driven transaction-manager="transactionManager"/>
-
-
-
-
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="realm"/>
- bean>
-
- <bean id="realm" class="com.qy151wd.realm.MyRealm">
- <property name="credentialsMatcher" ref="credentialsMatcher"/>
- bean>
-
-
- <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
- <property name="hashAlgorithmName" value="MD5"/>
- <property name="hashIterations" value="1024"/>
- bean>
-
-
- <bean id="lifecycleBeanPostProcessor"
- class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
- <bean
- class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
- depends-on="lifecycleBeanPostProcessor" />
- <bean
- class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager" />
- bean>
-
-
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager"/>
-
- <property name="filterChainDefinitions">
- <value>
- /login/upLogin=anon
- /**=authc
- value>
- property>
- <property name="filters">
- <map>
- <entry key="authc">
- <bean class="com.qy151wd.filter.LoginFilter"/>
- entry>
- map>
- property>
- bean>
-
- beans>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
- http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
- version="4.0">
-
- <servlet>
- <servlet-name>dispatcherServletservlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
-
- <init-param>
- <param-name>contextConfigLocationparam-name>
- <param-value>classpath:spring.xmlparam-value>
- init-param>
-
- <load-on-startup>1load-on-startup>
- servlet>
-
- <servlet-mapping>
- <servlet-name>dispatcherServletservlet-name>
- <url-pattern>/url-pattern>
- servlet-mapping>
-
- <filter>
- <filter-name>encodeFilterfilter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
- <init-param>
- <param-name>encodingparam-name>
- <param-value>UTF-8param-value>
- init-param>
- <init-param>
- <param-name>forceRequestEncodingparam-name>
- <param-value>trueparam-value>
- init-param>
- <init-param>
- <param-name>forceResponseEncodingparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>encodeFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
-
- <filter>
- <filter-name>shiroFilterfilter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
-
- <init-param>
- <param-name>targetFilterLifecycleparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>shiroFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
-
- web-app>
进入主页后,不同的用户可以看到不同的内容

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

上面只是在网页中根据不同用户显示不同的菜单,这种方式只能防君子不能防小人。
获取请求路径 然后根据你的路径判断当前用户是否具有该权限。
- 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;
- }
- }
可以加载相应方法上
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)
3.4.3 全局变量- @ControllerAdvice
- public class MyException {
- @ExceptionHandler(value = UnauthorizedException.class)
- @ResponseBody
- public CommonResult auth(UnauthorizedException e){
- e.printStackTrace();
- return new CommonResult(4002,"权限不足",null);
- }
- }
所谓前后端完全分离:后端响应的都是json数据,而不再是网页。
1. 登录成功或者失败应该返回json数据
2. 当未登录时返回的也是json数据
3. 访问未授权的资源,也要分会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;
- }
- }
注册过滤器 :注意路径




- @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);
- }
-
- }
- }
- @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";
- }
- }
- public interface LoginMapper {
-
- public User findByName(String username);
-
- public List
findPrimaryById(Integer userid); - }
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class User {
- private Integer userid;
-
- private String username;
-
- private String userpwd;
-
- private String sex;
-
- private String address;
-
- private String salt;
- }
- 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;
- }
- }
- @ControllerAdvice
- public class MyException {
- @ExceptionHandler(value = UnauthorizedException.class)
- @ResponseBody
- public CommonResult auth(UnauthorizedException e){
- e.printStackTrace();
- return new CommonResult(4002,"权限不足",null);
- }
- }
- 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;
- }
- }
- public interface LoginService {
-
- public User findByName(String username);
-
- public List
findPrimaryById(Integer userid); - }
- @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;
- }
- }
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class CommonResult {
- private Integer code;
- private String msg;
- private Object data;
- }
- mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.qy151wd.dao.LoginMapper">
- <sql id="userContent">
- userid,username,userpwd,sex,address,salt
- sql>
- <select id="findByName" parameterType="string" resultType="com.qy151wd.entity.User">
- select <include refid="userContent"/> from user where username=#{username}
- select>
-
- <update id="updateById">
- update user
- <set>
- <if test="username!=null and username!=''">
- username=#{username},
- if>
- <if test="userpwd!=null and userpwd!=''">
- userpwd=#{userpwd},
- if>
- <if test="sex!=null and sex!=''">
- sex=#{sex},
- if>
- <if test="address!=null and address!=''">
- address=#{address},
- if>
- <if test="salt!=null and salt!=''">
- salt=#{salt},
- if>
- set>
- where userid=#{userid}
- update>
-
- <insert id="insertUser">
- insert into user(userid,username,userpwd,sex,address,salt)
- values (null,#{username},#{userpwd},#{sex},#{address},#{salt})
- insert>
-
- <delete id="deleteById">
- delete from user where userid=#{userid}
- delete>
-
- <select id="findPrimaryById" resultType="string">
- select percode from
- user_role ur join role_permission rp on ur.roleid=rp.roleid
- join permission p on p.perid=rp.perid
- where ur.userid=#{userid};
- select>
- mapper>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
-
-
- <context:component-scan base-package="com.qy151wd.service,com.qy151wd.controller"/>
-
- <mvc:annotation-driven/>
-
- <mvc:default-servlet-handler/>
-
-
-
- <bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
-
- <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/project?serverTimezone=Asia/Shanghai"/>
- <property name="username" value="root"/>
- <property name="password" value="123456"/>
-
- <property name="initialSize" value="5"/>
-
- <property name="minIdle" value="5"/>
-
- <property name="maxActive" value="10"/>
-
- <property name="maxWait" value="3000"/>
- bean>
-
-
- <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="ds"/>
-
- <property name="mapperLocations" value="classpath:mapper/*.xml"/>
- bean>
-
-
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
-
- <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
-
- <property name="basePackage" value="com.qy151wd.dao"/>
- bean>
-
-
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="ds"/>
- bean>
-
- <tx:annotation-driven transaction-manager="transactionManager"/>
-
-
-
-
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="realm"/>
- bean>
-
- <bean id="realm" class="com.qy151wd.realm.MyRealm">
- <property name="credentialsMatcher" ref="credentialsMatcher"/>
- bean>
-
-
- <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
- <property name="hashAlgorithmName" value="MD5"/>
- <property name="hashIterations" value="1024"/>
- bean>
-
-
- <bean id="lifecycleBeanPostProcessor"
- class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
- <bean
- class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
- depends-on="lifecycleBeanPostProcessor" />
- <bean
- class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager" />
- bean>
-
-
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager"/>
-
- <property name="filterChainDefinitions">
- <value>
- /login/upLogin=anon
- /**=authc
- value>
- property>
- <property name="filters">
- <map>
- <entry key="authc">
- <bean class="com.qy151wd.filter.LoginFilter"/>
- entry>
- map>
- property>
- bean>
-
- beans>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
- http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
- version="4.0">
-
- <servlet>
- <servlet-name>dispatcherServletservlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
-
- <init-param>
- <param-name>contextConfigLocationparam-name>
- <param-value>classpath:spring.xmlparam-value>
- init-param>
-
- <load-on-startup>1load-on-startup>
- servlet>
-
- <servlet-mapping>
- <servlet-name>dispatcherServletservlet-name>
- <url-pattern>/url-pattern>
- servlet-mapping>
-
- <filter>
- <filter-name>encodeFilterfilter-name>
- <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
- <init-param>
- <param-name>encodingparam-name>
- <param-value>UTF-8param-value>
- init-param>
- <init-param>
- <param-name>forceRequestEncodingparam-name>
- <param-value>trueparam-value>
- init-param>
- <init-param>
- <param-name>forceResponseEncodingparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>encodeFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
-
- <filter>
- <filter-name>shiroFilterfilter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
-
- <init-param>
- <param-name>targetFilterLifecycleparam-name>
- <param-value>trueparam-value>
- init-param>
- filter>
-
- <filter-mapping>
- <filter-name>shiroFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
-
- web-app>
- <dependencies>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-webmvcartifactId>
- <version>5.2.15.RELEASEversion>
- dependency>
-
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.6version>
- dependency>
-
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatis-springartifactId>
- <version>2.0.6version>
- dependency>
-
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>8.0.28version>
- dependency>
-
-
- <dependency>
- <groupId>com.alibabagroupId>
- <artifactId>druidartifactId>
- <version>1.2.1version>
- dependency>
-
-
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- <version>1.18.24version>
- dependency>
-
-
- <dependency>
- <groupId>com.fasterxml.jackson.coregroupId>
- <artifactId>jackson-databindartifactId>
- <version>2.13.2.2version>
- dependency>
-
-
- <dependency>
- <groupId>javax.servletgroupId>
- <artifactId>javax.servlet-apiartifactId>
- <version>4.0.1version>
- dependency>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-jdbcartifactId>
- <version>5.2.15.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-txartifactId>
- <version>5.2.15.RELEASEversion>
- dependency>
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-aspectsartifactId>
- <version>5.2.15.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.mybatis.generatorgroupId>
- <artifactId>mybatis-generator-coreartifactId>
- <version>1.4.0version>
- dependency>
-
-
- <dependency>
- <groupId>log4jgroupId>
- <artifactId>log4jartifactId>
- <version>1.2.17version>
- dependency>
-
-
-
- <dependency>
- <groupId>org.apache.shirogroupId>
- <artifactId>shiro-springartifactId>
- <version>1.9.0version>
- dependency>
-
-
-
- dependencies>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
- <parent>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-parentartifactId>
- <version>2.3.12.RELEASEversion>
- <relativePath/>
- parent>
- <groupId>com.qy151wdgroupId>
- <artifactId>springboot_shiroartifactId>
- <version>0.0.1-SNAPSHOTversion>
- <name>springboot_shironame>
- <description>Demo project for Spring Bootdescription>
- <properties>
- <java.version>1.8java.version>
- properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-webartifactId>
- dependency>
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <scope>runtimescope>
- dependency>
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- <optional>trueoptional>
- dependency>
-
- <dependency>
- <groupId>com.baomidougroupId>
- <artifactId>mybatis-plus-boot-starterartifactId>
- <version>3.5.1version>
- dependency>
-
- <dependency>
- <groupId>org.apache.shirogroupId>
- <artifactId>shiro-spring-boot-starterartifactId>
- <version>1.7.0version>
- dependency>
-
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-testartifactId>
- <scope>testscope>
- dependency>
-
-
- <dependency>
- <groupId>com.spring4allgroupId>
- <artifactId>swagger-spring-boot-starterartifactId>
- <version>1.9.1.RELEASEversion>
- dependency>
- <dependency>
- <groupId>com.github.xiaoymingroupId>
- <artifactId>swagger-bootstrap-uiartifactId>
- <version>1.7.8version>
- dependency>
-
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-maven-pluginartifactId>
- <configuration>
- <excludes>
- <exclude>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- exclude>
- excludes>
- configuration>
- plugin>
- plugins>
- build>
-
- project>
- #数据源
- 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
- @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;
- }
- }
注意: (此处不进行修改会报错)

- 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;
}
doc.html无法访问以及样式无效。 shiro拦截规则拦截了 .
上边所给的依赖已经引入
com.spring4all swagger-spring-boot-starter 1.9.1.RELEASE com.github.xiaoymin swagger-bootstrap-ui 1.7.8
- @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", "2215854752@qq.com");
- ApiInfo apiInfo = new ApiInfo("萌萌的小项目", "适合小新手", "V1.0", "http://www.jd.com",
- DEFAULT_CONTACT, "牛牛公司", "http://www.taobao.com", new ArrayList
()); - return apiInfo;
- }
- }
上述配置shiro也已经释放此处的静态swigger资源


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