中国加油,武汉加油!
导shiro相关依赖
<dependency>
<groupId>org.apache.shirogroupId>
<artifactId>shiro-springartifactId>
<version>1.3.2version>
dependency>
application.properties配置模板引擎
# 配置模板引擎
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.cache=false
package com.wpj.config;
import com.wpj.realm.MyRealm;
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.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Shiro整个配置文件
*/
@SpringBootConfiguration
public class ShiroConfig {
private Logger logger = LoggerFactory.getLogger(ShiroConfig.class);
// 配置过滤器,拦截请求
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
logger.info("shiroFilterFactoryBean。。。。。。。");
// 认证失败跳转页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
/**
* logout: 登出过滤器
* perms:权限控制
* roles: 具有某一角色才能访问
*/
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("/login", "anon"); // anon匿名过滤器,不认证也可以访问
map.put("/**", "authc"); // authc认证过滤器:所有请求都必须在用户认证之后才能访问
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
// 配置安全管理器
// securityManager必须要跟上面的过来securityManager名字一致
@Bean
public DefaultWebSecurityManager securityManager(@Qualifier("myRealm") MyRealm myRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
logger.info("securityManager。。。。。。。");
// 设置校验的Realm对象
securityManager.setRealm(myRealm);
return securityManager;
}
// 配置Realm
// 名字同上
@Bean
public MyRealm myRealm(){
MyRealm myRealm = new MyRealm();
logger.info("myRealm。。。。。。。");
return myRealm;
}
}
package com.wpj.realm;
import com.wpj.pojo.User;
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.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* shiro跟数据库交互的桥梁
*/
public class MyRealm extends AuthorizingRealm {
@Override
public String getName() {
return "MyRealm";
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取用户名
String userName = (String) authenticationToken.getPrincipal();
// 通过用户名查询用户对象
// 查询出来(模拟数据库)
if(!(userName.equals("jiekami"))){
return null;
}
User user = new User(1,"jiekami","123");
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getName(), user.getPwd(), getName());
return simpleAuthenticationInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
}
package com.wpj.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private static final long serialVersionUID = 8434196542261610760L;
private Integer id;
private String name;
private String pwd;
}
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base th:href="${#request.getContextPath()+'/'}">
head>
<body>
this is index page!
body>
html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base th:href="${#request.getContextPath()+'/'}">
head>
<body>
<form action="/login" method="post">
姓名: <input type="text" name="name" /><span th:text="${nameError}">span><br />
密码: <input type="text" name="pwd" /><span th:text="${pwdError}">span><br />
<span th:text="${otherError}">span>
<input type="submit" value="登录">
form>
body>
html>
package com.wpj.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}
@RequestMapping("/toIndex")
public String toIndex(){
return "index";
}
@RequestMapping("/login")
public String login(User user, Model model) {
// 封装成请求对象
UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user.getPwd());
// 获取登录的主题对象
Subject subject = SecurityUtils.getSubject();
try{
// 登录
subject.login(token);
} catch (UnknownAccountException e) {
logger.error("未知账户异常");
model.addAttribute("nameError","未知账户异常");
return "login";
} catch (IncorrectCredentialsException e) {
logger.error("密码错误");
model.addAttribute("pwdError","密码错误");
return "login";
} catch (Exception e) {
logger.error("其他问题登录失败" + e.fillInStackTrace());
model.addAttribute("otherError","其他问题登录失败" + e.fillInStackTrace());
return "login";
}
return "index";
}
}
因为没连接数据库,springboot自动配置了url,如果不排除自动配置的类DataSourceAutoConfiguration会报错。
package com.wpj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base th:href="${#request.getContextPath()+'/'}">
head>
<body>
this is index page!
<a href="/logout">退出a>
body>
html>
map.put("/logout", "logout"); // logout登出过滤器
// 密码散列
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("MD5"); // MD5散列
hashedCredentialsMatcher.setHashIterations(1); // 散列次数
return hashedCredentialsMatcher;
}
User user = new User(1,"jiekami", "e99a18c428cb38d5f260853678922e03");
// 加盐
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
user.getName(), user.getPwd(), ByteSource.Util.bytes("abc"), getName());
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
user, user.getPwd(), ByteSource.Util.bytes("abc"), getName());
// 获取第一个参数 --》 SimpleAuthenticationInfo(user, user.getPwd(), ByteSource.Util.bytes("abc"), getName());
User user1 = (User)SecurityUtils.getSubject().getPrincipal();
model.addAttribute("user", user1);
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base th:href="${#request.getContextPath()+'/'}">
head>
<body>
欢迎<sapn th:text="${user.name}">sapn>登录<br />
this is index page!
<a href="/logout">退出a>
body>
html>