更新时间:2021-11-16 10:14:39 来源:极悦 浏览751次
关键词: Shiro Apache Java JSP
1.添加Shiro的依赖包,实现自己的Realm类(通过继承AuthorizingRealm类);
2.实现Shiro的配置类
3.实现前端登录界面和Controller类
步骤1:
在 pom.xml 中添加依赖包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
实现 Realm 类
package ariky.shiro.realm;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
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 org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.subject.WebSubject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @ClassName:
* @Description: Realm Configuration
* @author fuweilian
* @date 2018-5-12 11:36:41 am
*/
public class MyShiroRealm extends AuthorizingRealm {
//slf4j records logs, which can not be used
private Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
/**
* Set authorization information
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
logger.info("Start authorization(doGetAuthorizationInfo)");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils
.getSubject()).getServletRequest();//This can be used to obtain other additional parameter information submitted during login
String username = (String) principals.getPrimaryPrincipal();//This is the demo written here. Later, in the actual project, traditional Chinese medicine obtains the user's role and authority through the login account. This is written dead
//Acceptance authority
//role
Set<String> roles = new HashSet<String>();
roles.add("role1");
authorizationInfo.setRoles(roles);
//Jurisdiction
Set<String> permissions = new HashSet<String>();
permissions.add("user:list");
//permissions.add("user:add");
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
/**
* Set authentication information
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authenticationToken) throws AuthenticationException {
logger.info("Start certification(doGetAuthenticationInfo)");
//UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils
.getSubject()).getServletRequest();
UsernamePasswordToken token = new UsernamePasswordToken (request.getParameter("userName"),request.getParameter("password"));
//Get the account entered by the user
String userName = (String)token.getPrincipal();
//Go to the database to match the user information through userName, and do the following processing by querying the user's situation
//Write it dead for the time being, and deal with it according to the login user account
logger.info("Account number:"+userName);
if("passwordError".equals(userName)){//Password error
throw new IncorrectCredentialsException();
}else if("lockAccount".equals(userName)){// User locking
throw new LockedAccountException();
}else{
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
userName, //User name
"123456", //Password, write dead
ByteSource.Util.bytes(userName+"salt"),//salt=username+salt
getName() //realm name
);
return authenticationInfo;
}
}
}
第二步是实现Shiro的配置类:
package ariky.shiro.configuration;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ariky.shiro.realm.MyShiroRealm;
/**
* @ClassName: ShiroConfiguration
* @Description: shiro Configuration class
* @author fuweilian
* @date 2018-5-12 11:05:09 am
*/
@Configuration
public class ShiroConfiguration {
private static Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
logger.info("Get into shiroFilter......");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//Set a path that does not need to be blocked
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//Judge in order
filterChainDefinitionMap.put("/static/**", "anon");
//Configure the exit filter, the specific exit code Shiro has implemented for us
filterChainDefinitionMap.put("/logout", "logout");
//<!-- authc:All URLs must be authenticated to be accessible; anon: all URLs can be accessed anonymously -- >
/************************************Initialize all permission information start******************************************/
//Here, if you want to use it in a project later, you can query it directly from the database
filterChainDefinitionMap.put("/user/list", "authc,perms[user:list]");
//filterChainDefinitionMap.put("/user/add", "authc,perms[user:add]");
/***************************************Initialization of all permission information begins and ends*********************************************/
filterChainDefinitionMap.put("/**", "authc");
// If it is not set, it will automatically find the "/ login.jsp" page in the root directory of the Web project
shiroFilterFactoryBean.setLoginUrl("/login");
// Link to jump after successful login
shiroFilterFactoryBean.setSuccessUrl("/index");
//Unauthorized interface
shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
//You can set the caching mechanism here later
return myShiroRealm;
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
第三步:实现驱逐舰类。这里写了两个类。一个是登录信息的LoginController处理类,另一个是测试权限的UserController
1.登录控制器.java
package ariky.controller;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @ClassName: LoginController
* @Description: controller of login control
* @author fuweilian
* @date 2018-5-12 01:15:46 PM
*/
@RequestMapping
@Controller
public class LoginController {
private Logger logger = LoggerFactory.getLogger(LoginController.class);
@RequestMapping(value="/login",method=RequestMethod.GET)
public String getLogin(){
logger.info("Get into login page");
return "login";
}
@RequestMapping(value="/login",method=RequestMethod.POST)
public String doLogin(HttpServletRequest req,Map<String, Object> model){
logger.info("Enter login processing");
String exceptionClassName = (String) req.getAttribute("shiroLoginFailure");
logger.info("exceptionClassName:"+exceptionClassName);
String error = null;
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
error = "User name/Password error";
} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
error = "User name/Password error";
}else if(LockedAccountException.class.getName().equals(exceptionClassName)){
error = "User locked or deleted";
}else if (exceptionClassName != null) {
error = "Other errors:" + exceptionClassName;
}
if(SecurityUtils.getSubject().isAuthenticated()){//There is no error, but you have already signed in, and you can directly jump to the welcom page
model.put("name", req.getParameter("userName"));
return "index";
}else{//Erroneous
model.put("error", error);
return "login";
}
}
@RequestMapping("/index")
public String index(){
return "index";
}
}
2.UserController.java
package ariky.controller;
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @ClassName: UserController
* @Description: User processing Controller
* @author fuweilian
* @date 2018-5-12 03:11:06 PM
*/
@Controller
@RequestMapping("/user")
public class UserController {
Logger logger = LoggerFactory.getLogger(UserController.class);
@RequiresPermissions("user:list")//This is to configure whether this permission is available. If it is written according to the above method, this permission is available
@RequestMapping(value="/list",method=RequestMethod.GET)
public String getList(){
logger.info("Enter user list");
return "user/list";
}
@RequiresPermissions(value={"user:add"})//This is not authorized
@RequestMapping(value="/add",method=RequestMethod.GET)
public String getAdd(){
logger.info("Enter the new user interface");
return "user/add";
}
}
前端接口:有五个接口(login.jsp、index.jsp、list.jsp、add.jsp、403.jsp)
目录结构为:
1.登录.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login page----${error}</h1>
<form:form action="${pageContext.request.contextPath }/login"
method="post">
User name:<input type="text" name="userName">
<br />
Password:<input type="passwordParam" name="password"/>
<input type="submit" value="Submission"/>
</form:form>
</body>
</html>
2.index.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>First example</title>
<script src="${pageContext.request.contextPath }/webjars/jquery/2.1.4/jquery.js"></script>
<script src="${pageContext.request.contextPath }/webjarslocator/jquery/jquery.js"></script>
</head>
<body>
<h1>${name}:Hello, welcome to this website</h1>
<shiro:hasPermission name="user:list"><!-- this a The label is visible -->
<a href="${pageContext.request.contextPath }/user/list" target="_blank">Jump to user list(Have jurisdiction)</a>
</shiro:hasPermission>
<br/>
<shiro:hasPermission name="user:add"><!-- this a The label is invisible -->
<a href="${pageContext.request.contextPath }/user/add" target="_blank">Jump to new user list(No authority)</a>
</shiro:hasPermission>
</body>
</html>
3.list.jsp 与 add.jsp 和 403.jsp 几乎相同。这是一个。这只是为了演示。在实际项目中,以实际项目为准
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>userList</title>
</head>
<body>
<h1>User list information</h1>
</body>
</html>
如果启动成功,就可以进入登录登录界面测试shiro的权限认证。上面的代码都是写死的。如果要实现动态权限管理和用户权限管理,还需要做一些其他的处理。用户的动态权限只需要在他的ShiroRealm类中授权就可以查询数据库,动态授权和角色就可以了。对于动态权限管理,可以实现以下方法。修改权限数据后,只需更新shiro中的配置即可。具体看下面的代码。这是演示,而不是实际项目。在实际项目中,最好不要在Controller中写逻辑
package ariky.shiro.controller;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @ClassName: PermssionController
* @Description: controller of permission Operation
* @author fuweilian
* @date 2018-5-12 04:59:15 PM
*/
@Controller
@RequestMapping("permssion")
public class PermssionController {
@Autowired
ShiroFilterFactoryBean shiroFilterFactoryBean;
/**
* @Title: updatePermssion
* @author: fuweilian
* @Description: This is written in the controller for the time being. It is not written according to the rules. It will be written when it is used in the project
* @return Parameter description
* @return Object Return type
* @throws
*/
@RequestMapping("/updatePermssion")
@ResponseBody
public Object updatePermssion(){
synchronized (shiroFilterFactoryBean){
AbstractShiroFilter shiroFilter = null;
try {
shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean
.getObject();
PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
.getFilterChainResolver();
DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
.getFilterChainManager();
// Clear old permission control
manager.getFilterChains().clear();
shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
//The latter one can be obtained directly from the database
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//Judge in order
filterChainDefinitionMap.put("/static/**", "anon");
//Configure the exit filter, the specific exit code Shiro has implemented for us
filterChainDefinitionMap.put("/logout", "logout");
//<!-- authc:All URLs must be authenticated to be accessible; anon: all URLs can be accessed anonymously -- >
/************************************Initialize all permission information start******************************************/
//Here, if you want to use it in a project later, you can query it directly from the database
filterChainDefinitionMap.put("/user/list", "authc,perms[user:list]");
filterChainDefinitionMap.put("/user/add", "authc,perms[user:add]");
/***************************************Initialization of all permission information begins and ends*********************************************/
filterChainDefinitionMap.put("/**", "authc");
//
shiroFilterFactoryBean.setLoginUrl("/login");
// Link to jump after successful login
shiroFilterFactoryBean.setSuccessUrl("/index");
//Unauthorized interface
shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");
shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterChainDefinitionMap);
// Rebuild build
Map<String, String> chains = shiroFilterFactoryBean
.getFilterChainDefinitionMap();
for (Map.Entry<String, String> entry : chains.entrySet()) {
String url = entry.getKey();
String chainDefinition = entry.getValue().trim()
.replace(" ", "");
manager.createChain(url, chainDefinition);
}
return "Update permission succeeded";
} catch (Exception e) {
throw new RuntimeException(
"To update shiro Permission error!");
}
}
}
}
以上就是关于“SpringBoot中Shiro权限管理的集成使用”的介绍,如果您对此比较感兴趣,想了解更多相关知识,不妨来关注一下极悦的Shiro视频教程,里面的内容详细,通俗易懂,适合小白学习,希望对大家能够有所帮助。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习