java中的接口是类吗
272
2022-11-05
基于SpringBoot2的Shiro最简配置操作(两个文件)
基础环境:依赖
如果不是前后端分离,要实现页面级的权限控制,则加入以下依赖就可以使用shiro的权限标签了(记得在html头部加上相应约束:
lang="en">
):
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
.stream()
.map(SysUserRole::getRoleId)
.collect(Collectors.toSet());
//角色所有权限
Set
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
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.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
// 定制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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~