http://www.itwendao.com/article/detail/165400.htmlcss
http://www.itdadao.com/articles/c15a754492p0.htmlhtml
@Bean public EmbeddedServletContainerCustomizer containerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404")); container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500")); } }; }
http://www.cnblogs.com/xinzhao/p/4934247.html?utm_source=tuicool&utm_medium=referral前端
https://stackoverflow.com/questions/29783059/redirect-in-a-filter-with-spring-boot/29789630java
在spring security的內置login處理是沒法知足要求的,須要本身進行各類定製。這裏介紹login中實現驗證碼的實現。web
能夠有三種方法能夠實現驗證碼的功能spring
自定義一個filter,放在SpringSecurity過濾器以前,在用戶登陸的時候會先通過這個filter,而後在這個filter中實現對驗證碼進行驗證的功能,這種方法不推薦,由於它已經脫離了SpringSecurity服務器
自定義一個filter讓它繼承自UsernamePasswordAuthenticationFilter,而後重寫attemptAuthentication方法在這個方法中實現驗證碼的功能,若是驗證碼錯誤就拋出一個繼承自AuthenticationException的驗證嗎錯誤的異常好比(CaptchaException),而後這個異常就會被SpringSecurity捕獲到並將異常信息返回到前臺,這種實現起來比較簡單。
譬如:LoginAuthenticationFilter.javasession
import com.google.code.kaptcha.Constants; import com.tangcheng.app.domain.exception.CaptchaException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter { public LoginAuthenticationFilter() { AntPathRequestMatcher requestMatcher = new AntPathRequestMatcher("/login", "POST"); this.setRequiresAuthenticationRequestMatcher(requestMatcher); this.setAuthenticationManager(getAuthenticationManager()); // this.setAuthenticationFailureHandler(new LoginAuthenticationFailureHandler()); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String verification = request.getParameter("code"); String captcha = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY); if (!captcha.contentEquals(verification)) { throw new CaptchaException("captcha code not matched!"); } return super.attemptAuthentication(request, response); } }
java config:app
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
LoginAuthenticationFilter loginAuthenticationFilter = new LoginAuthenticationFilter();
loginAuthenticationFilter.setAuthenticationManager(authenticationManager());
loginAuthenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
....
http.authorizeRequests()
...框架
.addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
...
自定義的跳轉url,方便前端進行友好提示
@Bean public AuthenticationFailureHandler authenticationFailureHandler() { ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler(); Map<String, String> failureUrlMap = new HashMap<>(); failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL); failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.CODE_ERROR_URL); failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRED_URL); failureUrlMap.put(LockedException.class.getName(), LoginAuthenticationFailureHandler.LOCKED_URL); failureUrlMap.put(DisabledException.class.getName(), LoginAuthenticationFailureHandler.DISABLED_URL); failureHandler.setExceptionMappings(failureUrlMap); return failureHandler; }
或xml配置:
<bean id="loginFilter" class="com.zrhis.system.security.DefaultUsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"></property> <property name="authenticationSuccessHandler"> <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/index.jsp"></property> </bean> </property> <property name="authenticationFailureHandler"> <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.jsp"></property> </bean> </property> </bean>
最後在http中加入custom-filter配置,將這個filter放在SpringSecurity的FORM_LOGIN_FILTER以前.
<custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER"/>
直接替換掉SpringSecurity的UsernamePasswordAuthenticationFilter,這種比較複雜,可是更爲合理,也是我如今正在用的。
若是用這種方法那麼http 中的auto-config就必須去掉,而form-login配置也必須去掉,由於這個不須要了,裏面的屬性都須要咱們自行注入。
首先須要建立並配置一個login.jsp做爲登陸頁面EntryPoint
<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <property name="loginFormUrl" value="/login.jsp" /> </bean>
而後在http中配置下
<sec:http access-decision-manager-ref="accessDecisionManager" entry-point-ref="authenticationEntryPoint">
而後咱們來寫CaptchaAuthenticationFilter,一樣須要繼承自UsernamePasswordAuthenticationFilter
public class CaptchaAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "j_captcha"; public static final String SESSION_GENERATED_CAPTCHA_KEY = Constant.SESSION_GENERATED_CAPTCHA_KEY; private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY; public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String genCode = this.obtainGeneratedCaptcha(request); String inputCode = this.obtainCaptcha(request); if(genCode == null) throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaInvalid")); if(!genCode.equalsIgnoreCase(inputCode)){ throw new CaptchaException(this.messages.getMessage("LoginAuthentication.captchaNotEquals")); } return super.attemptAuthentication(request, response); } protected String obtainCaptcha(HttpServletRequest request){ return request.getParameter(this.captchaParameter); } protected String obtainGeneratedCaptcha (HttpServletRequest request){ return (String)request.getSession().getAttribute(SESSION_GENERATED_CAPTCHA_KEY); } }
Java Config:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
CaptchaAuthenticationFilter loginAuthenticationFilter = new CaptchaAuthenticationFilter();
loginAuthenticationFilter.setAuthenticationManager(authenticationManager());
loginAuthenticationFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
....
http.authorizeRequests()
...
.addFilterBefore(loginAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
...
自定義的跳轉url,方便前端進行友好提示
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() { ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler(); Map<String, String> failureUrlMap = new HashMap<>(); failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL); failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.CODE_ERROR_URL); failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRED_URL); failureUrlMap.put(LockedException.class.getName(), LoginAuthenticationFailureHandler.LOCKED_URL); failureUrlMap.put(DisabledException.class.getName(), LoginAuthenticationFailureHandler.DISABLED_URL); failureHandler.setExceptionMappings(failureUrlMap); return failureHandler; }
或XML配置:
在配置文件中配置CaptchaAuthenticationFilter
<bean id="captchaAuthenticaionFilter" class="com.zrhis.system.security.CaptchaAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationFailureHandler" ref="authenticationFailureHandler" /> <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" /> <property name="filterProcessesUrl" value="/login.do" /> </bean> <bean id="authenticationSuccessHandler" class="com.zrhis.system.security.SimpleLoginSuccessHandler"> <property name="defaultTargetUrl" value="/WEB-INF/app.jsp"></property> <property name="forwardToDestination" value="true"></property> </bean> <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.jsp" /> </bean>
從配置文件中就能夠看出來authenticationManager、authenticationFailureHandler、authenticationSuccessHandler、filterProcessesUrl等都須要咱們自行注入了。
filterProcessesUrl定義的是登陸驗證的地址,默認的是j_spring_security_check這裏咱們改爲login.do
authenticationSuccessHandler中的defaultTargetUrl定義的是登陸成功後跳轉到的頁面
authenticationFailureHandler中的defaultTargetUrl定義的是登陸失敗後跳轉到的頁面
咱們的首頁app.jsp在/WEB-INF下因此須要使用服務器跳轉,因此須要將forwardToDestination設爲true,由於客戶端跳轉是不能直接訪問WEB-INF下的內容的。
最後在http中將FORM_LOGIN_FILTER替換掉,最終http中完整的配置就變成了下面的內容
<sec:http access-decision-manager-ref="accessDecisionManager" entry-point-ref="authenticationEntryPoint"> <sec:access-denied-handler ref="accessDeniedHandler"/> <sec:session-management invalid-session-url="/login.jsp" /> <sec:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/> <sec:custom-filter ref="captchaAuthenticaionFilter" position="FORM_LOGIN_FILTER"/> </sec:http>
custom-filter中before是在這個filter以前,after是以後,position是替換。
http://www.infocool.net/kb/WWW/201701/268891.html
在使用Spring Security框架過程當中,常常會有這樣的需求,即在登陸驗證時,附帶增長額外的數據,如驗證碼、用戶類型等。下面將介紹如何實現。
注:個人工程是在Spring Boot框架基礎上的,使用xml方式配置的話請讀者自行研究吧。
該類提供了獲取用戶登陸時攜帶的額外信息的功能,默認實現WebAuthenticationDetails提供了remoteAddress與sessionId信息。開發者能夠經過Authentication的getDetails()獲取WebAuthenticationDetails。咱們編寫自定義類CustomWebAuthenticationDetails繼承自WebAuthenticationDetails,添加咱們關心的數據(如下是一個token字段)。
package com.courses.service; import javax.servlet.http.HttpServletRequest; import org.springframework.security.web.authentication.WebAuthenticationDetails; public class CustomWebAuthenticationDetails extends WebAuthenticationDetails { /** * */ private static final long serialVersionUID = 6975601077710753878L; private final String token; public CustomWebAuthenticationDetails(HttpServletRequest request) { super(request); token = request.getParameter("token"); } public String getToken() { return token; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()).append("; Token: ").append(this.getToken()); return sb.toString(); } }
注:在登陸頁面,可將token字段放在form表單中,也能夠直接加在url的參數中,進而把額外數據發送給後臺。
該接口用於在Spring Security登陸過程當中對用戶的登陸信息的詳細信息進行填充,默認實現是WebAuthenticationDetailsSource,生成上面的默認實現WebAuthenticationDetails。咱們編寫類實現AuthenticationDetailsSource,用於生成上面自定義的CustomWebAuthenticationDetails。
package com.courses.service; import javax.servlet.http.HttpServletRequest; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.stereotype.Component; @Component public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> { @Override public WebAuthenticationDetails buildDetails(HttpServletRequest context) { return new CustomWebAuthenticationDetails(context); } }
只要看這一句.formLogin().authenticationDetailsSource(authenticationDetailsSource)
@Autowired private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource; protected void configure(HttpSecurity http) throws Exception { http .headers() .cacheControl() .contentTypeOptions() .httpStrictTransportSecurity() .xssProtection() .and() .authorizeRequests() .antMatchers( "/css/**", "/js/**") .permitAll() .antMatchers("/**") .authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .defaultSuccessUrl("/todo.html", true) .authenticationDetailsSource(authenticationDetailsSource) .and() .logout() .logoutUrl("/logout") .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/login") .and() .csrf().disable(); }
AuthenticationProvider提供登陸驗證處理邏輯,咱們實現該接口編寫本身的驗證邏輯。
package com.courses.service; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Component; @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails(); // 如上面的介紹,這裏經過authentication.getDetails()獲取詳細信息 // System.out.println(details); details.getRemoteAddress(); details.getSessionId(); details.getToken(); // 下面是驗證邏輯,驗證經過則返回UsernamePasswordAuthenticationToken, // 不然,可直接拋出錯誤(AuthenticationException的子類,在登陸驗證不經過重定向至登陸頁時可經過session.SPRING_SECURITY_LAST_EXCEPTION.message獲取具體錯誤提示信息) if (驗證經過) { return UsernamePasswordAuthenticationToken(省略參數); } else { throw new AuthenticationException的子類("你要顯示的錯誤信息") } } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } }
@Autowired private AuthenticationProvider authenticationProvider; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authenticationProvider); }
http://www.cnblogs.com/phoenix-smile/p/5666686.html
@Bean public AuthenticationFailureHandler authenticationFailureHandler() { ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler(); Map<String, String> failureUrlMap = new HashMap<>(); failureUrlMap.put(AccountExpiredException.class.getName(), LoginAuthenticationFailureHandler.EXPIRE_URL); failureUrlMap.put(BadCredentialsException.class.getName(), LoginAuthenticationFailureHandler.PASS_ERROR_URL); failureUrlMap.put(CaptchaException.class.getName(), LoginAuthenticationFailureHandler.KAPTCHA_ERROR_URL); failureHandler.setExceptionMappings(failureUrlMap); return failureHandler; }
Caused by: java.lang.IllegalArgumentException: authenticationManager must be specified at org.springframework.util.Assert.notNull(Assert.java:134) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.afterPropertiesSet(AbstractAuthenticationProcessingFilter.java:164) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ... 24 common frames omitted
<sec:custom-filter position="FORM_LOGIN_FILTER" ref="formLoginFilter" /> <bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="filterProcessesUrl" value="/j_spring_security_check"/> <property name="usernameParameter" value="username "/> <property name="passwordParameter" value="password"/> <property name="authenticationSuccessHandler"> <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler "> <property name="alwaysUseDefaultTargetUrl" value="true"/> <property name="defaultTargetUrl" value="/success.jsp"/> </bean> </property> <property name="authenticationFailureHandler"> <!--bean class=" org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler "/--> <bean id="authenticationFailureHandler" class=" org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler"> <property name="exceptionMappings"> <props> <prop key="org.springframework.security.authentication.BadCredentialsException">/login/badCredentials</prop> <prop key="org.springframework.security.authentication.CredentialsExpiredException">/login/credentialsExpired</prop> <prop key="org.springframework.security.authentication.LockedException">/login/accountLocked</prop> <prop key="org.springframework.security.authentication.DisabledException">/login/accountDisabled</prop> </props> </property> </bean> </property> </bean>
http://www.jdon.com/dl/best/spring-security.html
最後就是最重要的security config 了:
import com.service.user.CustomerService; import com.web.filter.SiteMeshFilter; import com.web.mySecurity.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.StandardPasswordEncoder; import org.springframework.security.web.access.ExceptionTranslationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; import org.springframework.web.filter.CharacterEncodingFilter; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @Configuration @EnableWebSecurity public class SecurityConfig extends AbstractSecurityWebApplicationInitializer { @Bean public PasswordEncoder passwordEncoder() { return new StandardPasswordEncoder("MD5"); } @Autowired private CustomerService customerService; @Configuration @Order(1) public static class FrontendWebSecurityConfigureAdapter extends WebSecurityConfigurerAdapter { @Autowired private MyValidCodeProcessingFilter myValidCodeProcessingFilter; @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/user/login", "/user/logout").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(myValidCodeProcessingFilter, UsernamePasswordAuthenticationFilter.class) .formLogin() .loginPage("/user/login") .and() .logout() .logoutUrl("/user/logout") .logoutSuccessUrl("/user/login"); } } @Bean(name = "frontAuthenticationProvider") public MyAuthenticationProvider frontAuthenticationProvider() { MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider(); myAuthenticationProvider.setUserDetailsService(customerService); myAuthenticationProvider.setPasswordEncoder(passwordEncoder()); return myAuthenticationProvider; } @Bean public AuthenticationManager authenticationManager() { List<AuthenticationProvider> list = new ArrayList<>(); list.add(frontAuthenticationProvider()); AuthenticationManager authenticationManager = new ProviderManager(list); return authenticationManager; } @Bean public MyValidCodeProcessingFilter myValidCodeProcessingFilter(AuthenticationManager authenticationManager) { MyValidCodeProcessingFilter filter = new MyValidCodeProcessingFilter(); filter.setAuthenticationManager(authenticationManager); filter.setAuthenticationSuccessHandler(frontAuthenticationSuccessHandler()); filter.setAuthenticationFailureHandler(frontAuthenticationFailureHandler()); return filter; } @Bean public FrontAuthenticationFailureHandler frontAuthenticationFailureHandler() { return new FrontAuthenticationFailureHandler("/user/login"); } @Bean public FrontAuthenticationSuccessHandler frontAuthenticationSuccessHandler() { return new FrontAuthenticationSuccessHandler("/front/test"); } @Bean public MyAuthenticationEntryPoint myAuthenticationEntryPoint() { return new MyAuthenticationEntryPoint("/user/login"); } }
http://www.itwendao.com/article/detail/165400.html