Springboot + thymeleaf + shiro 小练习
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.security</groupId>
<artifactId>boot-security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>boot-security</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- 最高支持springboot2.0.9-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
ShiroConfig.java
package com.shiro.bootshiro.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Subject : 代表当前的用户
* SecurityManager : 安全管理器 管理者所有的用户
* Realm :用户的认证和授权
*/
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean 拦截配置
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultSecurityManager defaultSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultSecurityManager);
/**
* authc 需要通过认证
* anno 不需要权限可以访问
* perms 权限过滤器,需要某种权限才能访问
* roles 角色过滤器,需要某种角色才能访问
*/
Map<String, String> authMap = new LinkedHashMap<String, String>();
/*authMap.put("/index", "authc");
authMap.put("/", "authc");*/
/*authMap.put("/user/add", "perms[user:add]");
authMap.put("/user/update", "perms[user:update]");*/
shiroFilterFactoryBean.setFilterChainDefinitionMap(authMap);
shiroFilterFactoryBean.setLoginUrl("/toLogin");
// 没有权限跳转的页面
shiroFilterFactoryBean.setUnauthorizedUrl("/errorPage");
return shiroFilterFactoryBean;
}
//DefaultWebSecurityManager 安全管理器
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
defaultSecurityManager.setRealm(userRealm);
return defaultSecurityManager;
}
//Realm 认证和授权
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
// 整合ShiroDialect
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
/**
* 开启 aop 的注解支持
* 因为 shiro注解切面着手的,所以需要开启aop注解
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
/**
* 开启shiro 注解支持
*
* @RequiresPermissions 需要有权限才能访问
* @RequiresRoles 需要有角色才能访问
* @RequiresUser 必须已经经过身份验证或者记住我登录的才能访问
* @RequiresAuthentication 通过的身份验证的才能访问
* @RequiresGuest 游客的身份就可以访问
* <p>
* shiro 可以配置多个注解,按照以下的处理顺序,只有前面的通过了,才会处理下面的,不然直接返回
* RequiresRoles
* RequiresPermissions
* RequiresAuthentication
* RequiresUser
* RequiresGuest
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultSecurityManager defaultSecurityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
// 设置安全管理器
authorizationAttributeSourceAdvisor.setSecurityManager(defaultSecurityManager);
return authorizationAttributeSourceAdvisor;
}
}
UserRealm.java
package com.shiro.bootshiro.config;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.Arrays;
import java.util.List;
public class UserRealm extends AuthorizingRealm {
// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("===============进入授权===========");
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
String username = (String) principalCollection.getPrimaryPrincipal();
if ("root".equals(username)) {
simpleAuthorizationInfo.addStringPermission("user:add");
simpleAuthorizationInfo.addStringPermission("user:update");
simpleAuthorizationInfo.addRole("add");
simpleAuthorizationInfo.addRole("update");
}
if ("gao".equals(username)) {
simpleAuthorizationInfo.addStringPermission("user");
simpleAuthorizationInfo.addRole("add");
}
return simpleAuthorizationInfo;
}
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("===============进入认证===========");
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
// 后续这里可以对接数据库
String[] username = new String[]{"root", "gao", "guest"};
List<String> list = Arrays.asList(username);
String password = "root";
if (list.indexOf(usernamePasswordToken.getUsername()) < 0) {
return null;
}
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute("loginUser", usernamePasswordToken.getUsername());
return new SimpleAuthenticationInfo(usernamePasswordToken.getUsername(), password, "");
}
}
ShiroController.java
package com.shiro.bootshiro.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ShiroController {
@RequiresGuest()
@RequestMapping({"/", "/index"})
public String index() {
return "index";
}
@RequiresRoles({"add", "update"})
@RequestMapping("/user/add")
public String add() {
return "add";
}
@RequiresPermissions(value = {"user:update", "user:add"}, logical = Logical.OR)
@RequestMapping("/user/update")
public String update() {
return "update";
}
@RequestMapping("/login")
public ModelAndView login(String username, String password, ModelAndView modelAndView) {
// 获取当前用户
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
} catch (UnknownAccountException uae) { // 用户名错误
modelAndView.addObject("msg", "用户名错误");
modelAndView.setViewName("login");
return modelAndView;
} catch (IncorrectCredentialsException ice) { // 密码错误
modelAndView.addObject("msg", "密码错误");
modelAndView.setViewName("login");
return modelAndView;
}
modelAndView.setViewName("index");
return modelAndView;
}
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
@RequestMapping("/logout")
public String logOut() {
SecurityUtils.getSubject().logout();
return "login";
}
@RequestMapping("/errorPage")
public String errorPage() {
return "error";
}
}
页面太low了,就不挂出来了。。。。也不是重点
版权声明:本文为NotfoundExcption原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。