在 Spring Boot 中作權限管理,通常來講,主流的方案是 Spring Security ,可是,僅僅從技術角度來講,也可使用 Shiro。java
今天鬆哥就來和你們聊聊 Spring Boot 整合 Shiro 的話題!git
通常來講,Spring Security 和 Shiro 的比較以下:github
雖然 Shiro 功能簡單,可是也能知足大部分的業務場景。因此在傳統的 SSM 項目中,通常來講,能夠整合 Shiro。web
在 Spring Boot 中,因爲 Spring Boot 官方提供了大量的很是方便的開箱即用的 Starter ,固然也提供了 Spring Security 的 Starter ,使得在 Spring Boot 中使用 Spring Security 變得更加容易,甚至只須要添加一個依賴就能夠保護全部的接口,因此,若是是 Spring Boot 項目,通常選擇 Spring Security 。spring
這只是一個建議的組合,單純從技術上來講,不管怎麼組合,都是沒有問題的。apache
在 Spring Boot 中整合 Shiro ,有兩種不一樣的方案:後端
建立一個 Spring Boot 項目,只須要添加 Web 依賴便可:安全
項目建立成功後,加入 Shiro 相關的依賴,完整的 pom.xml 文件中的依賴以下:cookie
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
複製代碼
接下來咱們來自定義核心組件 Realm:session
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());
}
}
複製代碼
在 Realm 中實現簡單的認證操做便可,不作受權,受權的具體寫法和 SSM 中的 Shiro 同樣,不贅述。這裏的認證表示用戶名必須是 javaboy ,用戶密碼必須是 123 ,知足這樣的條件,就能登陸成功!
接下來進行 Shiro 的配置:
@Configuration
public class ShiroConfig {
@Bean
MyRealm myRealm() {
return new MyRealm();
}
@Bean
SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm());
return manager;
}
@Bean
ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager());
bean.setLoginUrl("/login");
bean.setSuccessUrl("/index");
bean.setUnauthorizedUrl("/unauthorizedurl");
Map<String, String> map = new LinkedHashMap<>();
map.put("/doLogin", "anon");
map.put("/**", "authc");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
複製代碼
在這裏進行 Shiro 的配置主要配置 3 個 Bean :
其中,ShiroFilterFactoryBean 的配置稍微多一些,配置含義以下:
這些東西都配置完成後,接下來配置登陸 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 接口:
而後調用 /doLogin 接口完成登陸:
再次訪問 /hello 接口,就能夠成功訪問了:
上面這種配置方式實際上至關於把 SSM 中的 XML 配置拿到 Spring Boot 中用 Java 代碼從新寫了一遍,除了這種方式以外,咱們也能夠直接使用 Shiro 官方提供的 Starter 。
建立成功後,添加 shiro-spring-boot-web-starter
,這個依賴能夠代替以前的 shiro-web
和 shiro-spring
兩個依賴,pom.xml 文件以下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
複製代碼
這裏的 Realm 和前面的同樣,我就再也不贅述。
接下來在 application.properties 中配置 Shiro 的基本信息:
shiro.sessionManager.sessionIdCookieEnabled=true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
shiro.unauthorizedUrl=/unauthorizedurl
shiro.web.enabled=true
shiro.successUrl=/index
shiro.loginUrl=/login
複製代碼
配置解釋:
@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;
}
}
複製代碼
這裏的配置和前面的比較像,可是再也不須要 ShiroFilterFactoryBean 實例了,替代它的是 ShiroFilterChainDefinition ,在這裏定義 Shiro 的路徑匹配規則便可。
這裏定義完以後,接下來的登陸接口定義以及測試方法都和前面的一致,我就再也不贅述了。你們能夠參考上文。
本文主要向你們介紹了 Spring Boot 整合 Shiro 的兩種方式,一種是傳統方式的 Java 版,另外一種則是使用 Shiro 官方提供的 Starter,兩種方式,不知道你們有沒有學會呢?
本文案例,我已經上傳到 GitHub ,歡迎你們 star:github.com/lenve/javab…
關於本文,有問題歡迎留言討論。
關注公衆號【江南一點雨】,專一於 Spring Boot+微服務以及先後端分離等全棧技術,按期視頻教程分享,關注後回覆 Java ,領取鬆哥爲你精心準備的 Java 乾貨!