在 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:https://github.com/lenve/javaboy-code-samples
關於本文,有問題歡迎留言討論。
關注公衆號牧碼小子,專一於 Spring Boot+微服務以及先後端分離等全棧技術,按期視頻教程分享,關注後回覆 Java ,領取鬆哥爲你精心準備的 Java 乾貨!