shiro介绍请移步shiro官网
1.创建springboot项目
使用spring初始化器创建即可
2.引入相关依赖
<!-- shiro依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.3</version>
</dependency>
3.配置shiro
写在前面,三个重要概念
Subject:代表当前用户,可以是一个人,也可以是第三方服务。在单应用中,可将其视为User的同义词。
SecurityManager:管理所有Subject,对于 Web 应用一般使用DefaultWebSecurityManager。
Realms:用于进行权限信息的验证,我们自己实现。是一个执行者,负责真正的认证和鉴权。
package com.almond.springbootshiro.common.config;
import com.almond.springbootshiro.common.realms.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* shiro配置类
*/
@Configuration
public class ShiroConfig {
// 1.创建shiroFilter 拦截所有请求
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
Map<String, String> map = new LinkedHashMap<>();
//设置系统公共资源 不需要认证和授权的资源
map.put("/user/login", "anon");
map.put("/user/register", "anon");
map.put("/register.jsp", "anon");
//设置系统受限资源 需要认证和授权的资源
map.put("/**", "authc"); //authc 请求需要授权和认证
//设置默认的资源路径
shiroFilterFactoryBean.setLoginUrl("/login.jsp");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
// 2.创建安全管理器
@Bean
public DefaultWebSecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//安全管理器设置realm
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
}
// 3.创建自定义的realm
@Bean
public Realm realm(HashedCredentialsMatcher hashedCredentialsMatcher) {
MyRealm myRealm = new MyRealm();
// 修改凭证校验匹配器
myRealm.setCredentialsMatcher(hashedCredentialsMatcher);
return myRealm;
}
}
package com.almond.springbootshiro.common.realms;
import com.almond.springbootshiro.mapper.TUserMapper;
import com.almond.springbootshiro.po.TUsers;
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 org.apache.shiro.util.ByteSource;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class MyRealm extends AuthorizingRealm {
@Resource
private TUserMapper tUserMapper;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
log.info("===============================");
//获取主身份信息
String principal = (String) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//添加身份权限
authorizationInfo.addRole("user");
//添加资源权限
List<String> strings = Arrays.asList("sys:user:add", "sys:user:update");
authorizationInfo.addStringPermissions(strings);
return authorizationInfo;
}
//验证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal = (String) authenticationToken.getPrincipal();
TUsers users = tUserMapper.getOne(principal);
if (null == principal || "".equals(principal)) {
// 推荐抛出自定义异常
throw new RuntimeException("token信息缺失");
}
if (principal.equals(users.getUsername())) {
if (null == users.getPassword() || "".equals(users.getPassword())) {
// 推荐抛出自定义异常
throw new RuntimeException("用户信息缺失");
}
return new SimpleAuthenticationInfo(principal, users.getPassword(), ByteSource.Util.bytes(users.getSlat()), getName());
}
return null;
}
}
package com.almond.springbootshiro.common.utils;
import java.util.Random;
public class SaltUtil {
public static String getSalt(Integer n) {
StringBuffer salt = new StringBuffer();
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}@!#$%^&*()<>?|".toCharArray();
for (int i = 0; i < n; i++) {
char aChar = chars[new Random().nextInt(chars.length)];
salt.append(aChar);
}
return salt.toString();
}
public static void main(String[] args) {
String salt = getSalt(5);
System.out.println(salt);
}
}
4.前端页面,使用jsp
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>主页</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a>
<ul>
<shiro:hasAnyRoles name="user,admin">
<li><a href="${pageContext.request.contextPath}/resource/one">资源一(user&&admin可见)</a></li>
<ul>
<shiro:hasPermission name="sys:user:add">
<li>添加</li>
</shiro:hasPermission>
<shiro:hasPermission name="sys:user:update">
<li>修改</li>
</shiro:hasPermission>
<shiro:hasPermission name="sys:user:*">
<li>查询</li>
</shiro:hasPermission>
</ul>
</shiro:hasAnyRoles>
<shiro:hasRole name="admin">
<li><a href="${pageContext.request.contextPath}/resource/two">资源二(admin可见)</a></li>
<li><a href="${pageContext.request.contextPath}/resource/three">资源二(admin可见)</a></li>
</shiro:hasRole>
</ul>
</body>
</html>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>登录</h1>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名: <input name="username" type="text"/><br/>
密码: <input name="password" type="password"/><br/>
<input value="登录" type="submit"/>
</form>
</body>
</html>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>注册</h1>
<form action="${pageContext.request.contextPath}/user/register" method="post">
用户名: <input type="text" name="username" /><br />
密码: <input type="password" name="password" /><br />
<input type="submit" value="注册">
</form>
</body>
</html>