Spring Security + JWT 實現基於Token的安全驗證
阿新 • • 發佈:2018-12-25
@Configuration @EnableWebSecurity //新增annotation 支援,包括(prePostEnabled,securedEnabled...) @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http. // 由於使用的是JWT,我們這裡不需要csrf csrf().disable() // 基於token,所以不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests() //所有使用者可以訪問"/resources"目錄下的資源以及訪問"/home"和favicon.ico .antMatchers("/resources/**", "/home","/**/favicon.ico","/auth/*").permitAll() //以"/admin"開始的URL,並需擁有 "ROLE_ADMIN" 角色許可權,這裡用hasRole不需要寫"ROLE_"字首; .antMatchers("/admin/**").hasRole("ADMIN") //以"/admin"開始的URL,並需擁有 "ROLE_ADMIN" 角色許可權和 "ROLE_DBA" 角色,這裡不需要寫"ROLE_"字首; .antMatchers("/dba/**").access("hasRole('ADMIN') and hasRole('DBA')") //前面沒有匹配上的請求,全部需要認證; .anyRequest().authenticated() .and() //指定登入介面,並且設定為所有人都能訪問; .formLogin().loginPage("/login").permitAll() //如果登入失敗會跳轉到"/hello" .successForwardUrl("/hello") .successHandler(loginSuccessHandler()) //如果登入失敗會跳轉到"/logout" //.failureForwardUrl("/logout") .and() .logout() .logoutUrl("/admin/logout") //指定登出的地址,預設是"/logout" .logoutSuccessUrl("/home") //登出後的跳轉地址login?logout //自定義LogoutSuccessHandler,在登出成功後呼叫,如果被定義則logoutSuccessUrl()就會被忽略 .logoutSuccessHandler(logoutSuccessHandler()) .invalidateHttpSession(true) //定義登出時是否invalidate HttpSession,預設為true //.addLogoutHandler(logoutHandler) //新增自定義的LogoutHandler,預設會新增SecurityContextLogoutHandler .deleteCookies("usernameCookie","urlCookie") //在登出同時清除cookies ; // 禁用快取 http.headers().cacheControl(); // 新增JWT filter http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); } @Autowired public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { authenticationManagerBuilder // 設定UserDetailsService .userDetailsService(this.userDetailsService) // 使用MD5進行密碼的加密 .passwordEncoder(passwordEncoder()); } private Md5PasswordEncoder passwordEncoder() { return new Md5PasswordEncoder(); } private AccessDeniedHandler accessDeniedHandler(){ AccessDeniedHandlerImpl handler = new AccessDeniedHandlerImpl(); handler.setErrorPage("/login"); return handler; } @Bean public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception { return new JwtAuthenticationTokenFilter(); } @Bean public LoginSuccessHandler loginSuccessHandler(){ LoginSuccessHandler handler = new LoginSuccessHandler(); return handler; } @Bean public LogoutSuccessHandler logoutSuccessHandler(){ return new LogoutSuccessHandler(); } }