簡體   English   中英

使用Spring Security在REST中記住我

[英]Remember me in REST using Spring security

我需要創建“記住我”提供的REST服務。 我的應用程序應接收帶有登錄數據的JSON,對用戶進行身份驗證,並使應用程序能夠記住該用戶。 我已經編寫了一些代碼片段,其中包含一些模擬的@RequestMapping和簡單的Spring安全配置,但是,應用程序對用戶進行了身份驗證(因為成功了Identification()過濾器的方法調用)。 但是,即使在登錄操作之后,即使我仍嘗試將請求發送到安全的url,它都會返回401代碼。 我知道,這很明顯新請求創建了一個新會話,但是有什么方法可以執行“記住我”行為而無需在每個請求的正文中發送登錄信息? 這是我的一些代碼:

package com.checkpoint.aimer.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

public class RestSecurityFilter extends AbstractAuthenticationProcessingFilter{

    public RestSecurityFilter(String url, AuthenticationManager m) {
        super(url);
        this.setAuthenticationManager(m);
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException,
            IOException, ServletException {
        HttpSession session = request.getSession();

        Authentication auth = this.getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken("roman", "sawawluha"));
        SecurityContextHolder.getContext().setAuthentication(auth);

        return auth;
    }
}

安全配置:

package com.checkpoint.aimer.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public RestSecurityFilter restSecurity() throws Exception {
        RestSecurityFilter filter = new RestSecurityFilter("/auth/login_test", authenticationManagerBean());
        return filter;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public UserDetailsService usr() {
        return new UserSecurityService();
    }

    @Override 
    public void configure(HttpSecurity http) throws Exception{
        http
            .httpBasic().authenticationEntryPoint(new AuthenticationEntryPoint() {

                @Override
                public void commence(HttpServletRequest request, HttpServletResponse response,
                        AuthenticationException arg2) throws IOException, ServletException {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Oops");

                }
            }).and()
            .addFilterBefore(restSecurity(),BasicAuthenticationFilter.class )
            .rememberMe().rememberMeServices(new TokenBasedRememberMeServices("key",usr()) ).and()
            .authorizeRequests()
                .antMatchers("/**").hasRole("USER")
                .antMatchers("/auth/**").anonymous()
                .and()
            .csrf().disable()
            .logout().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth
            .userDetailsService(usr());
    }



}

你有什么想法?

記住我,功能大部分是基於cookie實現的。 您可以將一些身份驗證令牌存儲到cookie中。 我相信您甚至可以為此使用會話Cookie。

但要記住:

  • 您必須一直使用HTTPS
  • 一直使用HttpOnly cookie屬性
  • 始終使用安全 Cookie屬性

因為cookie是隨每個請求發送給客戶端的,所以您需要確保它是通過安全通道發送的,並且不受跨站點攻擊的影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM