springSecurity實現簡單的登錄功能
前言
1、不使用數據庫,實現一個簡單的登錄功能,隻有在登錄後才能訪問我們的接口
2、springSecurity提供瞭一種基於內存的驗證方法(使用自己定義的用戶,不使用默認的)
一、實現用戶創建,登陸後才能訪問接口(註重用戶認證)
1.定義一個內存用戶,不使用默認用戶
重寫configure(AuthenticationManagerBuilder auth)方法,實現在內存中定義一個 (用戶名/密碼/權限:admin/123456/admin) 的用戶
package com.example.springsecurity; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.stereotype.Component; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //基於內存的驗證方法 auth.inMemoryAuthentication().withUser("admin").password("123456").roles("admin"); } @Override public void configure(WebSecurity web) throws Exception { //批處理靜態資源,都不攔截處理 web.ignoring().mvcMatchers("/js/**","/css/**","/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { // 這是一個重要的方法,這個方法決定瞭我們哪些請求會被攔截以及一些請求該怎麼處理 http.authorizeRequests() //安全過濾策略 .antMatchers("/").permitAll() .anyRequest().authenticated() .and() //and添加允許別的操作 .logout().permitAll() //允許支持註銷,支持隨意訪問 .and() .formLogin(); //允許表單登錄 http.csrf().disable(); //關閉csrf認證 } }
2.效果
根目錄可以直接通過驗證,其他接口需要經過springSecurity,輸入admin 123456後登陸系統
3.退出登陸
地址欄輸入:http://localhost:8080/login?logout,執行退出登陸
4.再創建一個張三用戶,同時支持多用戶登陸
package com.example.springsecurity; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.stereotype.Component; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //基於內存的驗證方法 auth.inMemoryAuthentication().withUser("admin").password("123456").roles("admin"); auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("admin"); } @Override public void configure(WebSecurity web) throws Exception { //批處理靜態資源,都不攔截處理 web.ignoring().mvcMatchers("/js/**","/css/**","/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { // 這是一個重要的方法,這個方法決定瞭我們哪些請求會被攔截以及一些請求該怎麼處理 http.authorizeRequests() //安全過濾策略 .antMatchers("/").permitAll() .anyRequest().authenticated() .and() //and添加允許別的操作 .logout().permitAll() //允許支持註銷,支持隨意訪問 .and() .formLogin(); //允許表單登錄 http.csrf().disable(); //關閉csrf認證 } }
二、實現管理員功能(註重權限控制)
實現角色功能,不同角色擁有不同功能:管理員擁有管理功能,而普通組員隻能擁有最普通的功能
1.創建一個普通用戶demo
auth.inMemoryAuthentication().withUser("demo").password("demo").roles("user");
創建demo用戶,角色為demo,詳細代碼如下
package com.example.springsecurity; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.stereotype.Component; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //基於內存的驗證方法 auth.inMemoryAuthentication().withUser("admin").password("123456").roles("admin"); auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("admin"); auth.inMemoryAuthentication().withUser("demo").password("demo").roles("user"); } @Override public void configure(WebSecurity web) throws Exception { //批處理靜態資源,都不攔截處理 web.ignoring().mvcMatchers("/js/**","/css/**","/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { // 這是一個重要的方法,這個方法決定瞭我們哪些請求會被攔截以及一些請求該怎麼處理 http.authorizeRequests() //安全過濾策略 .antMatchers("/").permitAll() .anyRequest().authenticated() .and() //and添加允許別的操作 .logout().permitAll() //允許支持註銷,支持隨意訪問 .and() .formLogin(); //允許表單登錄 http.csrf().disable(); //關閉csrf認證 } }
2.創建/roleAuth接口
此接口隻能admin角色才能登陸
1)、@EnableGlobalMethodSecurity註解使role驗證註解生效
2)、@PreAuthorize(“hasRole(‘ROLE_admin’)”)註解聲明哪個角色能訪問此接口
package com.example.springsecurity; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication @EnableGlobalMethodSecurity(prePostEnabled = true) //必須加這行,不然role驗證無效 public class SpringsecurityApplication { public static void main(String[] args) { SpringApplication.run(SpringsecurityApplication.class, args); } @RequestMapping("/") public String home(){ return "hello spring boot"; } @RequestMapping("/hello") public String hello(){ return "hello word"; } @PreAuthorize("hasRole('ROLE_admin')") //當我們期望這個方法經過role驗證的時候,需要加這個註解;ROLE必須大寫 @RequestMapping("/roleAuth") public String role(){ return "admin Auth"; } }
3.效果
demo用戶登陸成功可以訪問/接口,但是不能訪問/roleAuth接口
admin管理員既能訪問/接口,也能訪問/roleAuth接口
三、實現數據庫管理用戶(註重數據庫認證用戶)
1.我們需要把之前創建的admin zhangsan demo三個用戶放到數據庫中 2.我們需要使用MyUserService來管理這些用戶
1.創建一個MyUserService類
1.此類實現UserDetailsService(這邊不真實查詢數據庫)
package com.example.springsecurity; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Component; @Component public class MyUserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { return null;//數據庫操作邏輯 } }
2.密碼自定義驗證類
1.此類實現自定義密碼驗證
package com.example.springsecurity; import org.springframework.security.authentication.encoding.Md5PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; public class MyPasswdEncoder implements PasswordEncoder { private final static String SALT = "123456"; @Override public String encode(CharSequence rawPassword) { //加密:堆原始的密碼進行加密,這邊使用md5進行加密 Md5PasswordEncoder encoder = new Md5PasswordEncoder(); return encoder.encodePassword(rawPassword.toString(), SALT); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { //拿原始的密碼和加密後的密碼進行匹配 Md5PasswordEncoder encoder = new Md5PasswordEncoder(); return encoder.isPasswordValid(encodedPassword,rawPassword.toString(),SALT); } }
3.自定義數據庫查詢&默認數據庫查詢、自定義密碼驗證配置
1.支持自定義數據庫查詢 2.支持默認數據庫查詢(數據庫結構必須和默認的一致) 兩者選擇其中一個
package com.example.springsecurity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.stereotype.Component; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired MyUserService myUserService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //基於內存的驗證方法 // auth.inMemoryAuthentication().withUser("admin").password("123456").roles("admin"); // auth.inMemoryAuthentication().withUser("zhangsan").password("123456").roles("admin"); // auth.inMemoryAuthentication().withUser("demo").password("demo").roles("user"); //1、自己實現數據庫的查詢,指定我們要使用的UserService和自定義的密碼驗證器 auth.userDetailsService(myUserService).passwordEncoder(new MyPasswdEncoder()); //2、sprinSecurity在數據庫管理方面支持一套默認的處理,可以指定根據用戶查詢,權限查詢,這情況下用戶表必須和默認的表結構相同,具體查看user.ddl文件 auth.jdbcAuthentication().usersByUsernameQuery("").authoritiesByUsernameQuery("").passwordEncoder(new MyPasswdEncoder()); } @Override public void configure(WebSecurity web) throws Exception { //批處理靜態資源,都不攔截處理 web.ignoring().mvcMatchers("/js/**","/css/**","/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { // 這是一個重要的方法,這個方法決定瞭我們哪些請求會被攔截以及一些請求該怎麼處理 http.authorizeRequests() //安全過濾策略 .antMatchers("/").permitAll() .anyRequest().authenticated() .and() //and添加允許別的操作 .logout().permitAll() //允許支持註銷,支持隨意訪問 .and() .formLogin(); //允許表單登錄 http.csrf().disable(); //關閉csrf認證 } }
四、sprinSecurity支持的4種使用表達式的權限註解
1.支持的4種註解
@PreAuthorize("hasRole('ROLE_admin')") //1.方法調用前:當我們期望這個方法經過role驗證的時候,需要加這個註解;ROLE必須大寫 @PostAuthorize("hasRole('ROLE_admin')")//2.方法調用後 @PreFilter("")//2.對集合類的參數或返回值進行過濾 @PostFilter("")//2.對集合類的參數或返回值進行過濾 @RequestMapping("/roleAuth") public String role(){ return "admin Auth"; }
2.註解的參數該怎麼傳
or用法:
參數的值判斷
and運算
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SpringBoot 整合Security權限控制的初步配置
- java SpringSecurity使用詳解
- Spring boot整合security詳解
- Springboot開發OAuth2認證授權與資源服務器操作
- Spring Boot Admin的使用詳解(Actuator監控接口)