基于SpringBoot2的Shiro最简配置操作(两个文件)

网友投稿 452 2023-02-16

基于SpringBoot2的Shiro最简配置操作(两个文件)

基于SpringBoot2的Shiro最简配置操作(两个文件)

基础环境:依赖

org.springframework.boot

spring-boot-starter-parent

2.2.1.RELEASE

org.apache.shiro

shiro-spring-boot-starter

1.4.0

如果不是前后端分离,要实现页面级的权限控制,则加入以下依赖就可以使用shiro的权限标签了(记得在html头部加上相应约束:

lang="en">

):

com.github.theborakompanioni

thymeleaf-extras-shiro

2.0.0

Realm:认证鉴权器

package com.rz.monomer.modules.shiro;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.rz.monomer.modules.user.entity.SysUserInfo;

import com.rz.monomer.modules.user.entity.SysUserRole;

import com.rz.monomer.modules.user.service.SysButtonInfoService;

import com.rz.monomer.modules.user.service.SysUserInfoService;

import com.rz.monomer.modules.user.service.SysUserRoleService;

import lombok.extern.slf4j.Slf4j;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authc.SimpleAuthenticationInfo;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.authz.SimpleAuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

import java.util.Set;

import java.util.stream.Collectors;

/**

* 认证、鉴权类(必须)

*

* @author sunziwen

* @version 1.0

* @date 2019/11/14 14:06

**/

@Slf4j

public class ShiroRealm extends AuthorizingRealm {

//以下三个服务是普通Dao查询,从数据库查询用户及其角色权限信息(这个类没有自动注入,需要在下个文件中手动注入)

private SysUserInfoService userInfoService;

private SysButtonInfoService buttonInfoService;

private SysUserRoleService userRoleService;

public ShiroRealm(SysUserInfoService userInfoService, SysButtonInfoService buttonInfoService, SysUserRoleService userRoleService) {

this.userInfoService = userInfoService;

this.buttonInfoService = buttonInfoService;

this.userRoleService = userRoleService;

}

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

log.info("check authorization info");

SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();

// 获取当前用户

SysUserInfo userInfo = (SysUserInfo) principals.getPrimaryPrincipal();

// 查询角色信息

Set userRoles = userRoleService.list(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userInfo.getId()))

.stream()

.map(SysUserRole::getRoleId)

.collect(Collectors.toSet());

//角色所有权限

Set perms = buttonInfoService.getPermsByRoles(userRoles);

authInfo.addStringPermissions(perms);

return authInfo;

}

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

log.info("check authentication info");

String username = (String) token.getPrincipal();

// 获取用户信息

SysUserInfo user = userInfoService.getOne(new LambdaQueryWrapper().eq(SysUserInfo::getUsername, username));

if (user == null) {

return null;

}

/*SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),

ByteSource.Util.bytes(654321), getName());*/

SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), getName());

return authenticationInfo;

}

}

WebSecurityManager:安全管理器

package com.rz.monomer.modules.shiro;

import com.rz.monomer.modules.user.service.SysButtonInfoService;

import com.rz.monomer.modules.user.service.SysUserInfoService;

import com.rz.monomer.modules.user.service.SysUserRoleService;

import lombok.AllArgsConstructor;

import lombok.extern.slf4j.Slf4j;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;

import org.apache.shiro.web.filter.authc.LogoutFilter;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;

import java.util.LinkedHashMap;

import java.util.Map;

/**

* Shiro配置类(必须)

*

* @author sunziwen

* @version 1.0

* @date 2019/11/14 14:08

**/

@Configuration

@Slf4j

@AllArgsConstructor

public class WebSecurityManager {

private SysUserInfoService userInfoService;

private SysButtonInfoService buttonInfoService;

private SysUserRoleService userRoleService;

/**

* 安全管理器

*/

@Bean

public DefaultWebSecurityManager securityManager() {

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

securityManager.setRealm(realm());

return securityManager;

}

/**

* 认证鉴权器(安全管理器的依赖)

*/

@Bean

public ShiroRealm realm() {

return new ShiroRealm(userInfoService, buttonInfoService, userRoleService);

}

/**

* 配置拦截规则

*/

@Bean

public ShiroFilterFactoryBean filter(org.apache.shiro.mgt.SecurityManager securityManager) {

log.info("config shiro filter");

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

shiroFilterFactoryBean.setSecurityManager(securityManager);

// 定义URL拦截链

Map filterChainDefinitionMap = new LinkedHashMap();

// 允许匿名用户访问首页

filterChainDefinitionMap.put("/shiro/index", "anon");

// 定义注销路径

filterChainDefinitionMap.put("/shiro/logout", "logout");

// 所有用户界面都需要身份验证,否则会跳转到loginurl,由FormAuthenticationFilter处理

filterChainDefinitionMap.put("/shiro/user/**", "authc");

// 为login路径定义拦截,由FormAuthenticationFilter处理

filterChainDefinitionMap.put("/shiro/login", "authc");

// 所有vip路径要求具备vip角色权限

filterChainDefinitionMap.put("/shiro/vip/**", "roles[vip]");

// 指定loginurl 路径

shiroFilterFactoryBean.setLoginUrl("/shiro/login");

// 登录成功后跳转路径

shiroFilterFactoryBean.setSuccessUrl("/shiro/user/");

// for un authenticated

shiroFilterFactoryBean.setUnauthorizedUrl("/shiro/unauth");

shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

// 自定义filters,可覆盖默认的Filter列表,参考 DefaultFilter

Map filters = new LinkedHashMap();

// 定制logout 过滤,指定注销后跳转到登录页(默认为根路径)

LogoutFilter logoutFilter = new LogoutFilter();

logoutFilter.sDBMxajgeqetRedirectUrl("/shiro/login");

filters.put("logout", logoutFilter);

// 定制authc 过滤,指定登录表单参数

FormAuthenticationFilter authFilter = new FormAuthenticationFilter();

authFilter.setUsernameParam("username");

authFilter.setPasswordParam("password");

filters.put("authc", authFilter);

shiroFilterFactoryBean.setFilters(filters);

return shttp://hiroFilterFactoryBean;

}

}

Test:登录测试

package com.rz.monomer.modules.user.controller;

import com.rz.monomer.commons.utils.Md5Encrypt;

import lombok.extern.slf4j.Slf4j;

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.*;

import org.apache.shiro.authz.annotation.RequiresAuthentication;

import org.apache.shiro.subject.Subject;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.*;

@RestController

@Slf4j

public class LoginController {

@PostMapping("/login")

public String login(@RequestParam("username") String username, @RequestParam("password") String password) {

Subject subject = SecurityUtils.getSubject();

AuthenticationToken token = new UsernamePasswordToken(username, Md5Encrypt.md5(password));

try {

// 执行登录

subject.login(token);

} catch (UnknownAccountException e) {

// 未知用户

log.warn("the account {} is not found", username);

return "account not found";

} catch (IncorrectCredentialsException e) {

// 用户或密码不正确

log.warn("the account or password is not correct");

return "account or password not correct";

}

return "login success";

}

}

补充:SpringBoot配置Shiro时踩坑

在SpringBoot2.0整合shiro时使用@EnableAutoConfiguration的时候需要对config文件进行扫描,即使用@ComponentScan对配置进行扫描。

或者直接使用@SpringBootApplication,但是这种方法会将主方法目录下的所有package都进行扫描影响项目效率。

Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - zxc, rememberMe=false]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException

当出现此异常时,一般情况是用户名密码不匹配,或者是在配置对应的Realm时出现空值导致匹配失败。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决Springboot整合shiro时静态资源被拦截的问题
下一篇:关于注解式的分布式Elasticsearch的封装案例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~