JavaConfiguration для Spring 4.0 + Безопасность 3.2 + j_spring_security_check
-
Создайте страницу входа в систему
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Test</title>
<script src="static/js/jquery-1.10.2.min.js"></script>
<script src="static/js/app-controller.js"></script>
</head>
<body>
<div>Login</div>
<form name="f" action="<c:url value="/j_spring_security_check"/>" method="POST">
<label for="password">Username</label> <input type="text" id="j_username" name="j_username"><br/>
<label for="password">Password</label> <input type="password" id="j_password" name="j_password"><br/>
<input type="submit" value="Validate"> <input name="reset" type="reset">
<input type="hidden" id="${_csrf.parameterName}" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
<hr/>
<c:if test="${param.error != null}">
<div>
Failed to login.
<c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">
Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
</c:if>
</div>
</c:if>
<hr/>
<input type="button" value="Echo" id="echo" name="echo" onclick="AppController.echo();">
<div id="echoContainer"></div>
</body>
</html>
-
Объявить WebSecurityConfigurer ЗДЕСЬ, ГДЕ Я НЕ ПРОПУСТИТЬ j_username И j_password
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = {"com.sample.init.security"})
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Inject
private AuthenticationProvider authenticationProvider;
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/resources/**",
"/static/**",
"/j_spring_security_check",
"/AppController/echo.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter("j_username") /* BY DEFAULT IS username!!! */
.passwordParameter("j_password") /* BY DEFAULT IS password!!! */
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/")
.defaultSuccessUrl("/page")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/static/**");
}
}
-
Объявить WebMvcConfigurer
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {
"com.app.controller",
"com.app.service",
"com.app.dao"
})
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/page").setViewName("page");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("static/**").addResourceLocations("static/");
}
}
-
Объявить инициализатор безопасности
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer { }
-
Объявить приложение Initialzer
public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{WebSecurityConfigurer.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfigurer.class, DataSourceConfigurer.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
-
Внедрите свой собственный поставщик проверки подлинности
@Component
@ComponentScan(basePackages = {"com.app.service"})
public class CustomAuthenticationProvider implements AuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
@Inject
private AppService service;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//Thread.dumpStack();
String username = authentication.getName();
String password = authentication.getCredentials().toString();
String message = String.format("Username: '%s' Password: '%s'", username, password);
UserBean userBean = service.validate(username, password);
LOG.debug(message);
if (userBean != null) {
List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("USER"));
return new UsernamePasswordAuthenticationToken(userBean, authentication, grantedAuths);
} else {
String error = String.format("Invalid credentials [%s]", message);
throw new BadCredentialsException(error);
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
Я пропускаю EchoController, AppService, AppDao и UserBean.
Спасибо.
Ответы
Ответ 1
В версиях версии 3.2 параметры изменились с j_username на username и j_password на пароль. URL-адрес входа также изменился с /j _spring_security_check на/login.
Посмотрите эту ссылку, чтобы объяснить, почему это изменение было реализовано: http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#jc-httpsecurity. Это изменения:
-
GET/login отображает страницу входа вместо /spring _security_login
-
POST/login аутентифицирует пользователя вместо /j _spring_security_check
-
Параметр имени пользователя по умолчанию используется для имени пользователя вместо j_username
-
Параметр пароля по умолчанию использует пароль вместо j_password
И это для примера формы входа: http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#jc-form