一幌陕、基于配置的認(rèn)證與授權(quán)
新建controller
包
在該包下新建三個控制器荡含,AdminController,AppController,UserController
分別創(chuàng)建測試API
/**
* 模擬后臺相關(guān)Api接口
*/
@RequestMapping("/admin/api")
@RestController
public class AdminController {
?
@RequestMapping(value = "/hi",method = RequestMethod.GET)
public String hi(){
return "hi,admin.";
}
}
/**
* 模擬對外公開的Api接口
*/
@RequestMapping("/app/api")
@RestController
public class AppController {
?
@RequestMapping(value = "/hi", method = RequestMethod.GET)
public String hi() {
return "hi,app.";
}
}
/**
* 模擬用戶相關(guān)Api接口
*/
@RequestMapping("/user/api")
@RestController
public class UserController {
?
@RequestMapping(value = "/hi", method = RequestMethod.GET)
public String hi() {
return "hi,user.";
}
}
配置資源授權(quán)
配置configure
修改之前的配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/api/**").hasRole("ADMIN")
.antMatchers("/user/api/**").hasRole("USER")
.antMatchers("/app/api/**").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
// 指定處理登錄請求的路徑,修改請求的路徑飒赃,默認(rèn)為/login
.loginProcessingUrl("/mylogin")
// 使登錄頁面不設(shè)限訪問
.permitAll()
.and()
.csrf().disable();
}
antMatchers()
一個采用ANT模式的URL匹配器
? 表示匹配任意單個字符
* 表示匹配0或任意數(shù)量字符
** 表示匹配0或更多的目錄
重啟服務(wù)
訪問api http://localhost:8080/app/api/hi
訪問成功 頁面顯示 hi,app.
訪問api http://localhost:8080/user/api/hi
跳轉(zhuǎn)到登錄頁面
輸入自定義的用戶名密碼
登錄成功蜜托,頁面卻報403錯誤,表示授權(quán)失敗
認(rèn)證已經(jīng)通過微酬,授權(quán)失敗绘趋,以為我們配置的.antMatchers("/user/api/**").hasRole("USER")
,需要用戶具有USER角色權(quán)限
修改配置文件application.yml
spring:
security:
user:
name: caoshenyang
password: 123456
roles: USER
給用戶添加USER權(quán)限
重啟項目
訪問api http://localhost:8080/user/api/hi
登錄成功后颗管,頁面顯示hi,user.
訪問api http://localhost:8080/admin/api/hi
出現(xiàn)同樣情況
修改配置文件application.yml
給用戶添加上ADMIN權(quán)限
重啟項目
訪問正常陷遮,頁面顯示hi,admin.
二、基于內(nèi)存的多用戶設(shè)置
1. 實現(xiàn)自定義的UserDetailsService
@Bean
public UserDetailsService userDetailsService(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
//MD5 加密 明文 111 加密后 698d51a19d8a121ce581499d7b701668
//noop 明文
manager.createUser(User.withUsername("aa").password("{MD5}698d51a19d8a121ce581499d7b701668").roles("USER").build());
manager.createUser(User.withUsername("bb").password("{noop}222").roles("USER").build());
?
return manager;
}
注意:SpringSecurity5.x 以上版本需要配置加密否則會出現(xiàn)以下異常
There is no PasswordEncoder mapped for the id "null"
SpringSecurity5.x 加密方式采用{Id}password
的格式配置
我們可以看一下PasswordEncoderFactories自帶的加密方式
public class PasswordEncoderFactories {
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new LdapShaPasswordEncoder());
encoders.put("MD4", new Md4PasswordEncoder());
encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
?
private PasswordEncoderFactories() {
}
}
重新啟動
輸入賬號密碼
登錄成功
此配置會覆蓋原先application.yml
中的配置
2. 通過congfigure
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.withUser("tom").password("111").roles("ADMIN","USER")
.and()
.withUser("lisi").password("222").roles("USER");
}
同實現(xiàn)自定義UserDetailsService大同小異
此配置會覆蓋原先application.yml
中的配置
和自定義UserDetailsService中配置
選其中之一就可以