SpringSecurity(二)基於資料庫使用者登入
阿新 • • 發佈:2018-11-14
一、使用SpringSecurity提用的User物件
1. 新建一個MyUserService類
@Component public class MyUserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { // 省略從資料庫中獲取使用者資訊的過程... // 通過使用者名稱s去資料庫裡查詢使用者以及使用者許可權 // 然後返回User物件,注意,這裡的User物件是org.springframework.security.core.userdetails.User return new User(s,new BCryptPasswordEncoder().encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN,ROLE_USER")); } }
這個類實現了UserDetailsService介面,裡面有一個loadUserByUsername(String s)方法,這個方法返回一個UserDetails ,UserDetails 是一個介面,而org.springframework.security.core.userdetails.User實現了UserDetails,因此這裡我們可以直接使用SpringSecurity提供的User物件,當然如果不想使用SpringSecurity提供的User物件,我們也可以自己編寫一個實現UserDetails介面的物件。
2. SpringSecurityConfig類程式碼如下
@Configuration @EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserService myUserService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/authentication/*","/login") // 不需要登入就可以訪問 .permitAll() .antMatchers("/user/**").hasAnyRole("USER") // 需要具有ROLE_USER角色才能訪問 .antMatchers("/admin/**").hasAnyRole("ADMIN") // 需要具有ROLE_ADMIN角色才能訪問 .anyRequest().authenticated() .and() .formLogin() .loginPage("/authentication/login") // 設定登入頁面 .loginProcessingUrl("/authentication/form") .defaultSuccessUrl("/user/index") // 設定預設登入成功後跳轉的頁面 ; } // 密碼加密方式 @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } // 重寫方法,自定義使用者 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // auth.inMemoryAuthentication().withUser("lzc").password(new BCryptPasswordEncoder().encode("123456")).roles("ADMIN","USER"); // auth.inMemoryAuthentication().withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("USER"); auth.userDetailsService(myUserService); // 注入MyUserService,這樣SpringSecurity會呼叫裡面的loadUserByUsername(String s) } }
二、使用自定義的使用者物件
1. 新建一個LoginUser物件,拓展更多的使用者屬性
public class LoginUser implements UserDetails, CredentialsContainer {
private String password;
private String username;
private Set<GrantedAuthority> authorities;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
private String nickName;
public LoginUser() {
this("", "", true, true, true, true, null);
}
public LoginUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
this(username, password, true, true, true, true, authorities);
}
public LoginUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
if (username != null && !"".equals(username) && password != null) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.accountNonExpired = accountNonExpired;
this.credentialsNonExpired = credentialsNonExpired;
this.accountNonLocked = accountNonLocked;
this.authorities = new HashSet<>();
for (GrantedAuthority g : authorities) {
this.authorities.add(g);
}
} else {
throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
}
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public Set<GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<GrantedAuthority> authorities) {
this.authorities = authorities;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
@Override
public void eraseCredentials() {
this.password = null;
}
@Override
public boolean isAccountNonExpired() {
return this.accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return this.accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return this.credentialsNonExpired;
}
@Override
public boolean isEnabled() {
return this.enabled;
}
}
2. 修改MyUserService類
@Component
public class MyUserService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
// 省略從資料庫中獲取使用者資訊的過程...
// 通過使用者名稱s去資料庫裡查詢使用者以及使用者許可權
// 然後返回User物件,注意,這裡的User物件是org.springframework.security.core.userdetails.User
// return new User(s,new BCryptPasswordEncoder().encode("123456"),AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN,ROLE_USER"));
List<GrantedAuthority> authorityLists = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN,ROLE_USER");
LoginUser loginUser = new LoginUser(s,new BCryptPasswordEncoder().encode("123456"),authorityLists);
loginUser.setNickName("成");
return loginUser;
}
}
程式碼地址 https://github.com/923226145/SpringSecurity/tree/master/chapter2