目录
Spring Boot中使用Shiro
使用注解配置Shiro
1.导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
2.配置Shiro
Shiro配置主要配置3个Bean
①提供一个Realm的实例
②需要配置一个SecurityManager,在SecurityManager中配置Realm
③配置一个ShiroFilterFactoryBean,在ShiroFilterFactoryBean中指定路径拦截规则等
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(myRealm());
return defaultWebSecurityManager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager()); // 指定会话管理器SecurityManager
bean.setLoginUrl("/login"); // 指定登录页面
bean.setSuccessUrl("/index"); // 指定登录成功页面
bean.setUnauthorizedUrl("/unauthorizedurl");
// Map中配置了路径拦截规则,注意:要有序
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin", "anon");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
3.自定义核心组件Realm
在Realm中实现简单的认证操作即可,不做授权;授权的具体写法和SSM中的Shiro一样
此认证:用户名必须是admin,用户密码必须是123,满足这样的条件,就能登录成功
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if (!"admin".equals(username)) {
throw new UnknownAccountException("账户不存在!");
}
return new SimpleAuthenticationInfo(username, "123", getName());
}
}
4.配置登录Controller
@RestController
public class LoginController {
@PostMapping("/doLogin")
public void doLogin(String username, String password) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
System.out.println("登录成功!");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("登录失败!");
}
}
@GetMapping("/hello")
public String hello() {
return "hello";
}
@GetMapping("/login")
public String login() {
return "please login!";
}
}
测试:首先访问/hello接口,由于未登录,所以会自动跳转到/login接口
使用启动器(Starter)
Spring Boot 2.3.0版本使用Shiro 1.5.3。使用Shiro官方提供的一个Starter来配置,但是,这个Starter并没有简化多少配置
1.导入shiro-web启动器
项目创建成功后,加入Shiro相关的依赖
<!-- Shiro启动器 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.5.3</version>
</dependency>
2.修改配置文件
application.properties中配置Shiro的基本信息
#开启shiro
shiro.web.enabled=true
#是否允许将sessionId 放到 cookie 中
shiro.sessionManager.sessionIdCookieEnabled=true
#是否允许将 sessionId 放到 Url 地址拦中
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
#访问未获授权的页面时,默认的跳转路径
shiro.unauthorizedUrl=/unauthorizedurl
#登录成功的跳转页面
shiro.successUrl=/index
#登录页面
shiro.loginUrl=/login
3.自定义核心组件Realm
在Realm中实现简单的认证操作即可,不做授权,授权的具体写法和SSM中的Shiro一样
public class MyRealm extends AuthorizingRealm {
// 授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
// 认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if (!"javaboy".equals(username)) {
throw new UnknownAccountException("账户不存在!");
}
return new SimpleAuthenticationInfo(username, "123", getName());
}
}
4.配置类
这里的配置和前面的比较像,但是不再需要ShiroFilterFactoryBean实例,替代它的是 ShiroFilterChainDefinition,在这里定义Shiro的路径匹配规则即可
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
definition.addPathDefinition("/doLogin", "anon");
definition.addPathDefinition("/**", "authc");
return definition;
}
}
4.配置登录Controller
@RestController
public class LoginController {
@PostMapping("/doLogin")
public void doLogin(String username, String password) {
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
System.out.println("登录成功!");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("登录失败!");
}
}
@GetMapping("/hello")
public String hello() {
return "hello";
}
@GetMapping("/login")
public String login() {
return "please login!";
}
}
测试:首先访问/hello接口,由于未登录,所以会自动跳转到/login接口