总结SpringBoot整合Shiro的流程
一、配置依赖
<!--继承springboot-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.7.RELEASE</version>
</parent>
<dependencies>
<!--shiro的启动器依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.2</version>
</dependency>
<!--thymeleaf的启动器依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
二、编写配置文件
新建application.yml
#登录验证
shiro:
loginUrl: /showLogin
三、新建实体类
新建com.bjsxt.pojo.User
package com.bjsxt.pojo;
public class User {
private Long id;
private String username;
private String password;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != null ? !id.equals(user.id) : user.id != null) return false;
if (username != null ? !username.equals(user.username) : user.username != null) return false;
return password != null ? password.equals(user.password) : user.password == null;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
return result;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public User() {
}
}
四、编写业务层代码
新建com.bjsxt.service.UserService及实现类
package com.bjsxt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class,args);
}
}
package com.bjsxt.service.impl;
import com.bjsxt.pojo.User;
import com.bjsxt.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
public User selectByUsername(String username) {
//没有使用数据库,直接使用固定数据,用户名必须是admin,密码是admin
if (username.equals("wollo")) {
return new User(1L, "wollo", "52cbebae9797d6ff5807cd3cb334ca6d");
}
return null;
}
}
五、自定义Realm
新建com.bjsxt.realm.MyRealm编写认证逻辑
package com.bjsxt.realm;
import com.bjsxt.pojo.User;
import com.bjsxt.service.UserService;
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.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userServiceImpl;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行认证");
String username = token.getPrincipal().toString();
User user = userServiceImpl.selectByUsername(username);
if (user!=null){
AuthenticationInfo info =
new SimpleAuthenticationInfo(token.getPrincipal(),user.getPassword(), ByteSource.Util.bytes("gyc"),user.getUsername());
return info;
}
return null;
}
}
六、编写配置
新建com.bjsxt.config.ShiroConfig,编写配置
package com.bjsxt.config;
import com.bjsxt.realm.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig {
//声明自定义realm属性
@Autowired
private MyRealm myRealm;
//配置securityManager,并设置realm为自定义的realm
@Bean
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
hashedCredentialsMatcher.setHashIterations(2);
myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
//
defaultWebSecurityManager.setRealm(myRealm);
defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
return defaultWebSecurityManager;
}
/**
* cookie 属性设置
*/
public SimpleCookie rememberMeCookie()
{
SimpleCookie cookie = new SimpleCookie("rememberMe");
// cookie.setDomain(domain);
cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setMaxAge(30 * 24 * 60 * 60);
return cookie;
}
/**
* 记住我
*/
public CookieRememberMeManager rememberMeManager()
{
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode("MTIzNDU2NzgxMjM0NTY3OA=="));
return cookieRememberMeManager;
}
//配置shiro的过滤器
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin","anon");
definition.addPathDefinition("/logout", "logout");
definition.addPathDefinition("/**", "user");
return definition;
}
}
七、编写控制器
新建com.bjsxt.controller.UserController
package com.bjsxt.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/doLogin")
public String userLogin(String username,String password){
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken(username,password,true);
try {
subject.login(token);
return "redirect:/showIndex";
}catch (Exception e){
e.printStackTrace();
}
return "redirect:/showLogin";
}
@RequestMapping("/showIndex")
public String showIndex(){
System.out.println("showIndex");
return "index";
}
@RequestMapping("/showLogin")
public String showLogin(){
System.out.println("showLogin");
return "login";
}
}
八、编写启动类
新建com.bjsxt.ShiroApplication
package com.bjsxt.service;
import com.bjsxt.pojo.User;
public interface UserService {
User selectByUsername(String username);
}
九、编写页面
- 1.编写登录界面
新建templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/doLogin" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password" /><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
- 2.编写主界面
新建templates/index.html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
dasiuohjasioukdhoaisdjhoailsdjoasdji
<a href="/logout">退出</a>
</body>
</html>