SpringMVC with rest controller - Request method 'POST' not supported - spring

I have application in SpringMVC with Spring Security. In spring security xml configuration file i enable csrf using <csrf/>. View in html work properly when i add csrf token to link in form but now i want add Controller and made some rest communication. Controller looks like this:
#Controller
public class RestControllerTest {
#RequestMapping(value = "/rest", method = RequestMethod.POST, produces = "application/json")
#ResponseStatus(value = HttpStatus.OK)
public #ResponseBody void setUser(#RequestBody User user){
System.out.println("Witaj " + user.getFirstname() + "!");
}
}
When i try to send JSon with user (using postman):
{
"firstname": "name",
"lastname": "name"
}
I get 404 not found status in postman and WARN : org.springframework.web.servlet.PageNotFound - Request method 'POST' not supported in STS. I know that I have to use csrf token but i don't have idea how to do this.

I have a similar working usecase as yours. This is how things look like in my case.
My Filter class -
public class MyCsrfFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain)
throws Exception {
CsrfToken csrf = (CsrfToken) request.getAttribute(org.springframework.security.web.csrf.CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath(YOUR_DOMAIN_NAME);
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
Below is the security configuration in spring-boot. You can convert it to equivalent xml config file if you need one.
#Configuration
#EnableWebMvcSecurity
public class CustomWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.csrfTokenRepository(getTokenRepo())
.and()
.authorizeRequests()
.antMatchers("/login", "/login**").permitAll()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
}
private CsrfTokenRepository getTokenRepo() {
HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
repo.setHeaderName("X-XSRF-TOKEN");
return repo;
}
Hope this helps !

Related

403 after login with OAuth 2

I am using Spring Security 5 and I implemented the login but everytime I try to call other URL after login I get a 403 Unhautorized. My doFilterInternal is not even called (it is for the login though).
It gets on org.springframework.security.web.session.SessionManagementFilter#doFilter but it has no security context or authentication present neither a session.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig {
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Autowired
private CustomOAuth2UserService customOAuth2UserService;
#Autowired
private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
#Autowired
private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;
#Autowired
private HttpCookieOAuth2AuthorizationRequestRepository httpCookieOAuth2AuthorizationRequestRepository;
#Bean
public TokenAuthenticationFilter tokenAuthenticationFilter() {
return new TokenAuthenticationFilter();
}
/*
By default, Spring OAuth2 uses HttpSessionOAuth2AuthorizationRequestRepository to save
the authorization request. But, since our service is stateless, we can't save it in
the session. We'll save the request in a Base64 encoded cookie instead.
*/
#Bean
public HttpCookieOAuth2AuthorizationRequestRepository cookieAuthorizationRequestRepository() {
return new HttpCookieOAuth2AuthorizationRequestRepository();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests()
.requestMatchers( "/auth/login").permitAll()
.anyRequest().authenticated();
return http.build();
}
}
HttpCookieOAuth2AuthorizationRequestRepository
#Component
public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {
public static final String OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME = "oauth2_auth_request";
public static final String REDIRECT_URI_PARAM_COOKIE_NAME = "redirect_uri";
private static final int cookieExpireSeconds = 180;
#Override
public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {
return CookieUtils.getCookie(request, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME)
.map(cookie -> CookieUtils.deserialize(cookie, OAuth2AuthorizationRequest.class))
.orElse(null);
}
#Override
public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, HttpServletResponse response) {
if (authorizationRequest == null) {
CookieUtils.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME);
CookieUtils.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME);
return;
}
CookieUtils.addCookie(response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME, CookieUtils.serialize(authorizationRequest), cookieExpireSeconds);
String redirectUriAfterLogin = request.getParameter(REDIRECT_URI_PARAM_COOKIE_NAME);
if (StringUtils.isNotBlank(redirectUriAfterLogin)) {
CookieUtils.addCookie(response, REDIRECT_URI_PARAM_COOKIE_NAME, redirectUriAfterLogin, cookieExpireSeconds);
}
}
#Override
public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) {
return this.loadAuthorizationRequest(request);
}
// #Override
// public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) {
// return this.loadAuthorizationRequest(request);
// }
public void removeAuthorizationRequestCookies(HttpServletRequest request, HttpServletResponse response) {
CookieUtils.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME);
CookieUtils.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME);
}
}
You are missing the resource-server configuration in your HTTP config with either JWT decoder or token introspection ("opaqueToken" in spring security configuration DSL). Sample configuration from this tutorials I wrote:
#Bean
SecurityFilterChain filterChain(HttpSecurity http,
Converter<Jwt, AbstractAuthenticationToken> authenticationConverter,
ServerProperties serverProperties)
throws Exception {
// Enable OAuth2 with custom authorities mapping
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(authenticationConverter);
// Enable and configure CORS
http.cors().configurationSource(corsConfigurationSource());
// State-less session (state in access-token only)
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Disable CSRF because of state-less session-management
http.csrf().disable();
// Return 401 (unauthorized) instead of 302 (redirect to login) when
// authorization is missing or invalid
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\"");
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
});
// Route security: authenticated to all routes but actuator and Swagger-UI
// #formatter:off
http.authorizeHttpRequests()
.requestMatchers("/actuator/health/readiness", "/actuator/health/liveness", "/v3/api-docs", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
.anyRequest().authenticated();
// #formatter:on
return http.build();
}
OAuth2 login is for clients (server side rendered UI with template engine like Thymeleaf or JSF) and requires sessions (and CSRF protection), not for resource-servers (REST APIs) which should respond to unauthorized requests to secured resources with 401 (unauthorized) and not 302 (redirect to login). Use a certified OpenID client lib in your client to manage redirection to authorization server, token acquisition and refreshing, and requests authorization (setting of Authorization header with access-token).
You asked for SessionCreationPolicy.STATELESS and it's what you get.
If there is no "state", there is no recording of the fact that the user has logged in successfully. It's a setup for REST services not for UI interaction.

Redirect to original URL after successful authentication in Spring Security

I have the following security configuration class in a Spring Cloud Gateway application. This gateway acts as an OAuth2 client handling the user authentication. After a successful authentication, I'd like to redirect to the URL of the single-page application where the user originally came from.
Example
If the user was on http://localhost:8093/profile then this should be the redirect URL.
Currently I only use a hardcoded value which works for testing purposes. Is there a way to get the "original URL" and use it as a redirection URL?
#Configuration
#EnableWebFluxSecurity
public class SecurityConfiguration {
#Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity httpSecurity) {
httpSecurity
.csrf().disable()
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2Login()
// Use original URL here?
.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("http://localhost:8093"))
.and()
.exceptionHandling().authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
.oauth2ResourceServer().jwt();
return httpSecurity.build();
}
}
You can try below provide the combination to Achieve what you are looking for:
First of all you need to create your Authentication Success Handler:
public class MySimpleUrlAuthenticationSuccessHandler
implements AuthenticationSuccessHandler {
protected Log logger = LogFactory.getLog(this.getClass());
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException {
handle(request, response, authentication);
clearAuthenticationAttributes(request);
}
Then handle Method implementation:
protected void handle(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication
) throws IOException {
//This will provide you last URL
String targetUrl = request.getHeader("referer");
if (response.isCommitted()) {
logger.debug(
"Response has already been committed. Unable to redirect to "
+ targetUrl);
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
Just an FYI:
Note: the HTTP referer is a client-controlled value and can thus be spoofed to something entirely different or even removed. This value should not be used for any critical operation.
Maybe it's too late, but I had the same problem like you. Has Jayesh said, you need to create a class "Authentication Success Handler" to add some logic and redirection after a sucessfull Oauth2 authentication.
But this new class , instead of extending SimpleUrlAuthenticationSucessHandler, must extends SavedRequestAwareAuthenticationSucessHandler and override the method onAuthenticationSucess().
public class OAuth2LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
#Autowired
private UserService userService;
#Autowired
private MessageSource messageSource;
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal();
User existingUser = userService.findByUsername(oAuth2User.getEmail());
if (existingUser != null) {
// update of user with providerId and authenticationProvider if not already done
log.info(messageSource.getMessage("global.existing-user.oauth2-authenticated",
new Object[] { existingUser }, LocaleContextHolder.getLocale()));
if (existingUser.getAuthenticationProvider() == AuthProvider.LOCAL) {
userService.updateUserFromOAuth2Authentication(oAuth2User, existingUser);
} else if ((!Objects.equals(existingUser.getIdProvider(), oAuth2User.getproviderId())
|| existingUser.getAuthenticationProvider() != oAuth2User.getClientProvider())) {
throw new OAuth2AuthenticationException("a problem occured with Oauth2Authentication!");
}
} else {
// creation of new user
log.info(messageSource.getMessage("global.not-existing-user.oauth2-authenticated",
new Object[] { "createdUser" }, LocaleContextHolder.getLocale()));
userService.saveUserFromOAuth2Authentication(oAuth2User);
}
super.onAuthenticationSuccess(request, response, authentication);
}
}
In your configuration class for security, you just have to call the method successHandler()for Oauth2Login to use your new class "authentication success handler" without of course, using method defaultSucessUrl() , like this
http.oauth2Login()
.loginPage("/app/login")
.userInfoEndpoint()
.userService(oauth2UserService)
.and()
.successHandler(oAuth2LoginSuccessHandler)
;
Sorry for my bad english, i found this solution just after reading this article https://www.baeldung.com/spring-security-redirect-login

URL access denying when implementing the Spring Security for URL authentication

I am trying to implement URL authentication before it giving the response through business logic. For that I am using the authentication provider from Spring Security and trying to do one simple demo for testing authenticationProvider working properly. After this I am going to modify by adding my business logic.
My security config file SecurityConfig.java like the following,
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider authenticationProvider;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.anyRequest()
.authenticated()
.and().httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.authenticationProvider(authenticationProvider);
}
}
And My CustomAuthenticationProvider.java implementation like the following,
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider
{
#SuppressWarnings("unused")
#Override
public Authentication authenticate(Authentication authToken) throws AuthenticationException {
String userToken = (String) authToken.getName();
String responseString = "test";
String password = "test";
if(responseString.equals(userToken)) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userToken, password);
return auth;
}
else {
return null;
}
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
And my TestSecurity.java like the following,
#RestController
public class TestSecurity {
#GetMapping("/security/load")
public String LoadSecureUsers() {
return "hello spring security";
}
}
When I am calling the URL localhost:8585/security/load with headers authToken: "test" from POSTMAN application, I am getting the following,
{
"timestamp": "2019-10-30T07:24:25.165+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/security/load"
}
If the condition are satisfying in IF, then how the URL is not able to access? Did I make any mistake in authentication Provider implementation?
Instead of AuthenticationProvider use filter to process the request. This code might help you:
public class ApplicationAuthFilter extends BasicAuthenticationFilter {
public ApplicationAuthFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = String bearerToken = req.getHeader("accessToken");
String username = "test";
String password = "test"
if (username != null && !username.isEmpty()) {
return new UsernamePasswordAuthenticationToken(username, null, authorities);
}
return null;
}
}
And your security config file like this:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilter(new ApplicationAuthFilter(authenticationManager()))
}
}
Basically you need to read the header information which you are passing with request and based on that you have to take action.
Hope this helps.

How to do basic authentication using cookies in spring security?

I am securing my REST api using Basic-Auth. On correct credentials passed by user, a controller is responsible for sending a httpOnly and secure cookie in response.
#GetMapping
#ResponseStatus(value=HttpStatus.OK)
public void loginUser( final HttpServletRequest request ,final HttpServletResponse response) throws UnsupportedEncodingException {
setAuthCookieToResonse(request,response);
}
private void setAuthCookieToResonse(final HttpServletRequest request ,final HttpServletResponse response) throws UnsupportedEncodingException {
String cookieKey = "auth";
String cookieValue = request.getHeader("Authorization");
if (cookieValue != null) {
Cookie cookie = new Cookie(cookieKey, cookieValue);
cookie.setHttpOnly(true);
cookie.setSecure(true);
response.addCookie(cookie);
}
}
So, now with each request a cookie is being sent by the browser, which will contain Basic-Auth details. But the problem is, how do the spring security extract those credentials from that cookie?
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {// #formatter:off
httpSecurity
.cors()
.and().authorizeRequests()
.antMatchers("/signup/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable()
;
}
My guess was:
To add a filter before BasicAuthenticationFilter.class and extract the credentials from cookie and than add those credentials to the HttpServletRequest's Authorizaton header which is going to be passed to spring-security layer. But the problem is, HttpServletRequest doesn't have API to add headers.
What would be the right way to implement this?
I made this working after following this blog (archived). But I would love to hear other solutions, especially using some spring configuration itself. Spring is a very matured framework, it must(should) have something to handle this common problem.
Since, the HttpServletRequest don't have any method to add the new headers, I need to create a custom class which can add new headers to the request, this can be achived by HttpServletRequestWrapper. Here is the implementation.
public final class MutableHttpServletRequest extends HttpServletRequestWrapper {
// holds custom header and value mapping
private final Map<String, String> customHeaders;
public MutableHttpServletRequest(HttpServletRequest request) {
super(request);
this.customHeaders = new HashMap<String, String>();
}
public void putHeader(String name, String value) {
this.customHeaders.put(name, value);
}
public String getHeader(String name) {
// check the custom headers first
String headerValue = customHeaders.get(name);
if (headerValue != null) {
return headerValue;
}
// else return from into the original wrapped object
return ((HttpServletRequest) getRequest()).getHeader(name);
}
public Enumeration<String> getHeaderNames() {
// create a set of the custom header names
Set<String> set = new HashSet<String>(customHeaders.keySet());
// now add the headers from the wrapped request object
Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
while (e.hasMoreElements()) {
// add the names of the request headers into the list
String n = e.nextElement();
set.add(n);
}
// create an enumeration from the set and return
return Collections.enumeration(set);
}
}
The filter which checks for the cookie, before the Spring-secuirty:
public class CheckAuthCookieFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(getClass());
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(httpServletRequest);
Cookie[] cookies = httpServletRequest.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
logger.debug(cookie.getName() + " : " + cookie.getValue());
if (cookie.getName().equalsIgnoreCase("auth")) {
mutableRequest.putHeader("Authorization", URLDecoder.decode(cookie.getValue(), "utf-8"));
}
}
}
chain.doFilter(mutableRequest, response);
}
}
and finally the security configuration:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {// #formatter:off
httpSecurity
.cors()
.and().authorizeRequests()
.antMatchers("/signup/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable()
;
httpSecurity.addFilterBefore(new CheckAuthCookieFilter(), BasicAuthenticationFilter.class);
}
My custom filter will run before the Spring's BasicAuthenticationFilter.If there is a cookie present with name auth(which the application created on successful login), than that's the cookie which holds the basic auth credentials. The credentials are extracted from that, and added to the header of request. Then the BasicAuthenticationFilter will run and look for the Authorization and proceed with its normal flow.

spring boot + security + jquery ajax

Hi,I build a project with spring boot & spring security. Now, I want to provider the login restfull service for Jquery.ajax({...}); And I want to:
process the login request from HTML page (like the <form> submit).
automatic to check session timeout when HTML page request, redirect timeout to login page.
process the login request from Ajax.
automatic to check the login state when Ajax request.
I coding like this
SecurityConfig
extends from WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
String requestType = request.getHeader("x-requested-with");
if (!StringUtils.isEmpty(requestType)) {
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().print("{\"invalid_session\": true}");
response.getWriter().flush();
} else {
response.sendRedirect("/security/login");
}
});
http.authorizeRequests()
.antMatchers("/security/**").permitAll()
.antMatchers("/reader/**").hasRole("READER")
.anyRequest().authenticated()
// session time out
.and().sessionManagement().invalidSessionUrl("/security/session_timeout")
.and().cors()
// login
.and()
.formLogin()
.successHandler(successHandler)
.failureHandler(faildHandler)
.loginPage("/security/login")
.permitAll()
// logout
.and()
.logout().permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(readerRepository::findOne);
}
I have two handlers to process AuthenticationSuccess and AuthenticationFailure.
FailureHandler
extends from SimpleUrlAuthenticationFailureHandler
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
System.out.println("Failed to auth.");
String requestType = request.getHeader("x-requested-with");
if (!StringUtils.isEmpty(requestType)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print("{\"success\": false}");
} else {
setDefaultFailureUrl("/security/login?error=true");
super.onAuthenticationFailure(request, response, exception);
}
}
SuccessHandler
extends from SavedRequestAwareAuthenticationSuccessHandler
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println("Success to auth.");
String requestType = request.getHeader("x-requested-with");
if (!StringUtils.isEmpty(requestType)) {
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().print("{\"success\": true}");
} else {
setDefaultTargetUrl("/index/index");
setAlwaysUseDefaultTargetUrl(true);
super.onAuthenticationSuccess(request, response, authentication);
}
}
Controller
base RequestMapping is '/security'
#RequestMapping(value = "/login")
public String login(#RequestParam(value = "error", defaultValue = "false") boolean error, Model model) {
model.addAttribute("error", error);
return "login";
}
#RequestMapping("/session_timeout")
public void sessionTimeout(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("session was timeout.");
if (request.getHeader("x-requested-with") != null) {
// handler for ajax
response.getWriter().print("{\"sessionTimeout\": true}");
response.getWriter().close();
} else {
response.sendRedirect("login");
}
}
When I test in page(thymeleaf), All of worked.
but.. when I use Jquery Ajax.
The issure:
When I used Jquery.ajax({}) API to send the request, the request can not be get to server. How to write ajax request with jquery, I tried a lot of Jquery methods, page has no response code in console. Is the spring security not support ajax?
Thanks Fan, I fixed it. I rewrote the login authentication:
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, userReq.getPassword(), userDetails.getAuthorities());
authenticationManager.authenticate(token);
if (token.isAuthenticated()) {
SecurityContextHolder.getContext().setAuthentication(token);
return true;
}
Do auth with AuthenticationManager and it injected from spring.
If success to auth, I will return the sessionid to the client and client saved in cookie, when client do request, the client always stats sessionid at the end of the url requested by ajax.
If failed to auth, I wile return agreed error code.
eg:
$.ajax({
url: 'http://test:port/project/list;jsessionid=' + jessionid,
...
})
But I do not think so is good job like this. It's very troublesome, In the client,I need to check every response code is it right or not for every request. Is any better ways to solve this ensure??
by the way, the Client(Browser + Ajax) and Server(Spring mvc) are separate.

Resources