sprring Security和shiro都是當前最流行的兩個認真框架,一直都沒有去學習,這段時間疫情的影響,一直在家辦公,晚上的時候找時間學習了一下,spring Security,而且shiro的學習也是比較模糊,都沒完整的瞭解過整個流程,接下來的一段時間先進行一下了解,出一系列的筆記.跟多配置參考:https://github.com/wuyouzhuguli/SpringAll ,github上發現的項目,初學者十分的實用
配置流程
- 引入pom依賴
- 創建user實體
- 配置userdetailservice,重寫loaduserByUsername方法,用於數據庫的查詢用戶的對象,獲取權限等
- 配置登錄成功和失敗的handler
- 配置SecurityConfig
pom依賴
<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>1.5.14.RELEASE/<version>
<relativepath>
<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-security/<artifactid>
user實體
user實體需要實現 UserDetails接口
<code>public class MyUser implements Serializable, UserDetails {/<code>
<code> private static final long serialVersionUID = 3497935890426858541L;/<code>
<code> /<code>
<code> private String username;/<code>
<code> /<code>
<code> private String password;/<code>
<code> /<code>
<code> private boolean accountNonExpired = true;/<code>
<code> /<code>
<code> private boolean accountNonLocked= true;/<code>
<code> /<code>
<code> private boolean credentialsNonExpired= true;/<code>
<code> /<code>
<code> private boolean enabled= true;/<code>
<code> @Override/<code>
<code> public String getUsername() {/<code>
<code> return username;/<code>
<code> }/<code>
<code> /<code>
<code> public void setUsername(String userName) {/<code>
<code> this.username = userName;/<code>
<code> }/<code>
<code> /<code>
<code> /****/<code>
<code> *實現userDetail的發方法/<code>
<code> *//<code>
<code> @Override/<code>
<code> public Collection extends GrantedAuthority> getAuthorities() {/<code>
<code> return null;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public String getPassword() {/<code>
<code> return password;/<code>
<code> }/<code>
<code> @Override/<code>
<code> public boolean isAccountNonExpired() {/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isAccountNonLocked() {/<code>
<code> return accountNonLocked;/<code>
<code> }/<code>
<code> public void setAccountNonExpired(boolean accountNonExpired) {/<code>
<code> this.accountNonExpired = accountNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isAccountNonLocked() {/<code>
<code> return accountNonLocked;/<code>
<code> }/<code>
<code> public void setAccountNonLocked(boolean accountNonLocked) {/<code>
<code> this.accountNonLocked = accountNonLocked;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isCredentialsNonExpired() {/<code>
<code> return credentialsNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> public void setCredentialsNonExpired(boolean credentialsNonExpired) {/<code>
<code> this.credentialsNonExpired = credentialsNonExpired;/<code>
<code> }/<code>
<code> /<code>
<code> @Override/<code>
<code> public boolean isEnabled() {/<code>
<code> return enabled;/<code>
<code> }/<code>
<code> /<code>
<code> public void setEnabled(boolean enabled) {/<code>
<code> this.enabled = enabled;/<code>
<code> }/<code>
<code>}/<code>
userdetailService
實現UserDetailsService接口,實現loaduseByUsername 方法輸入mapper方法,通過用戶名返回user對象,這裡模擬查找到用戶的情況, PasswordEncoder 配置密碼的加密模式,
<code>@Configuration/<code>
<code>public class UserDetailService implements UserDetailsService {/<code>
<code> @Autowired/<code>
<code> private PasswordEncoder passwordEncoder;/<code>
<code> /<code>
<code> @Override/<code>
<code> public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {/<code>
<code> // 模擬一個用戶,替代數據庫獲取邏輯/<code>
<code> MyUser user = new MyUser();/<code>
<code> user.setUsername(username);/<code>
<code> user.setPassword(this.passwordEncoder.encode("123456"));/<code>
<code> // 輸出加密後的密碼/<code>
<code> System.out.println(user.getPassword());/<code>
<code> /<code>
<code> return new User(username, user.getPassword(), user.isEnabled(),/<code>
<code> user.isAccountNonExpired(), user.isCredentialsNonExpired(),/<code>
<code> user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));/<code>
<code> }/<code>
<code> }/<code>
失敗handler和成功的hanlder
成功和失敗的日誌記錄.跳轉的頁面等
登錄成功的攔截器,實現接口AuthenticationSuccessHandler,重寫方法,成功後跳轉到index
<code>@Component/<code>
<code>public class MyAuthenticationSucessHandler implements AuthenticationSuccessHandler {/<code>
<code> /<code>
<code> /<code>
<code> private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();/<code>
<code> /<code>
<code> @Override/<code>
<code> public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,/<code>
<code> Authentication authentication) throws IOException {/<code>
<code> redirectStrategy.sendRedirect(request, response, "/index");/<code>
<code> }/<code>
<code>}/<code>
登錄失敗提示異常信息
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Autowired
private ObjectMapper mapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(mapper.writeValueAsString(exception.getMessage()));
}
}
配置Securityconfig 最後一步,配置SecurityConfig
<code>@Configuration/<code>
<code>public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {/<code>
<code> //handler/<code>
<code> @Autowired/<code>
<code> private MyAuthenticationSucessHandler authenticationSuccessHandler;/<code>
<code> /<code>
<code> @Autowired/<code>
<code> private MyAuthenticationFailureHandler authenticationFailureHandler;/<code>
<code> /<code>
<code> /<code>
<code> @Override/<code>
<code> protected void configure(HttpSecurity http) throws Exception {/<code>
<code> http.formLogin() // 表單登錄/<code>
<code> // http.httpBasic() // HTTP Basic/<code>
<code> .loginPage("/login.html") // 登錄跳轉 URL/<code>
<code> .loginProcessingUrl("/login") // 處理表單登錄 URL/<code>
<code> .successHandler(authenticationSuccessHandler) // 處理登錄成功/<code>
<code> .failureHandler(authenticationFailureHandler) // 處理登錄失敗/<code>
<code> .and()/<code>
<code> .authorizeRequests() // 授權配置/<code>
<code> .antMatchers("/authentication/require", "/login.html").permitAll() // 登錄跳轉 URL 無需認證/<code>
<code> .anyRequest() // 所有請求/<code>
<code> .authenticated() // 都需要認證/<code>
<code> .and().csrf().disable();/<code>
<code> }/<code>
<code> /<code>
<code>//加密模式/<code>
<code> @Bean/<code>
<code> public PasswordEncoder passwordEncoder() {/<code>
<code> return new BCryptPasswordEncoder();/<code>
<code> }/<code>
<code> /<code>
<code>}/<code>
基本的搭建流程就這些,下一篇介紹驗證碼,記住我,短信驗證碼的實現;
如果此處看著不方便,請移步http://xs-shuai.com/?p=73
閱讀更多 編程的boy 的文章