03.01 spring Security 快速搭建

sprring Security和shiro都是當前最流行的兩個認真框架,一直都沒有去學習,這段時間疫情的影響,一直在家辦公,晚上的時候找時間學習了一下,spring Security,而且shiro的學習也是比較模糊,都沒完整的瞭解過整個流程,接下來的一段時間先進行一下了解,出一系列的筆記.跟多配置參考:https://github.com/wuyouzhuguli/SpringAll ,github上發現的項目,初學者十分的實用


配置流程

  1. 引入pom依賴
  2. 創建user實體
  3. 配置userdetailservice,重寫loaduserByUsername方法,用於數據庫的查詢用戶的對象,獲取權限等
  4. 配置登錄成功和失敗的handler
  5. 配置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


分享到:


相關文章: