使用Spring Security保护REST Api

时间:2016-12-08 19:51:59

标签: java rest spring-mvc spring-security

我是Spring Security的新手,我试图在我的应用程序中保护REST api。我有应用程序URIS然后我有一个像" / api / v1 /"我的休息时间。

我已使用用户名/密码身份验证保护我的应用程序,并且它工作正常,但现在我想保护我的REST api返回401 Unauthorized如果用户未经过身份验证,但我没有'知道如何将两个身份验证保持在一起。

这是怎么回事?

PS:我正在使用Spring MVC和Spring Security

这是我现在的Spring Security配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AccountService accountService;

    @Bean
    public TokenBasedRememberMeServices rememberMeServices() {
        return new TokenBasedRememberMeServices("remember-me-key", accountService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new StandardPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.eraseCredentials(true).userDetailsService(accountService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/favicon.ico", "/resources/**", "/signup").permitAll().anyRequest()
                .authenticated()
                .and().formLogin().loginPage("/signin").permitAll().failureUrl("/signin?error=1")
                .loginProcessingUrl("/authenticate")
                .and().logout().logoutUrl("/logout").permitAll().logoutSuccessUrl("/signin?logout")
                .and().rememberMe().rememberMeServices(rememberMeServices()).key("remember-me-key")
                .and().csrf();
    }

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

2 个答案:

答案 0 :(得分:1)

所以你想要表格登录和安全休息api吗?

jhipster可以生成这样的项目结构。如果您不想使用jhipster,我会举一些示例代码来实现这个目标(虽然我推荐它很酷)

为了未经授权而返回401,你需要这样的东西:

/**
 * Returns a 401 error code (Unauthorized) to the client.
 */
@Component
public class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint {

    private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class);

    /**
     * Always returns a 401 error code to the client.
     */
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2)
        throws IOException,
        ServletException {

        log.debug("Pre-authenticated entry point called. Rejecting access");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Access Denied");
    }
}

然后注入并将其添加到您的SecurityConfig.configure(HttpSecurity http)方法中:

http.authenticationEntryPoint(authenticationEntryPoint)

此外,由于REST请求是ajax请求,因此您还需要ajax入口点:

/**
 * Returns a 401 error code (Unauthorized) to the client, when Ajax authentication fails.
 */
@Component
public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException exception) throws IOException, ServletException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed");
    }
}


/**
 * Spring Security success handler, specialized for Ajax requests.
 */
@Component
public class AjaxAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication)
        throws IOException, ServletException {

        response.setStatus(HttpServletResponse.SC_OK);
    }
}

/**
 * Spring Security logout handler, specialized for Ajax requests.
 */
@Component
public class AjaxLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
    implements LogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication)
        throws IOException, ServletException {
        response.setStatus(HttpServletResponse.SC_OK);
    }
}

将它们添加到安全配置中:

http.successHandler(ajaxAuthenticationSuccessHandler)
    .failureHandler(ajaxAuthenticationFailureHandler)
    .logoutSuccessHandler(ajaxLogoutSuccessHandler)

所有功劳归功于惊人的jhipster作者。

答案 1 :(得分:-2)

您可以使用基于表达式的访问控制 http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html

类似的东西,

<intercept-url pattern=/** access="isFullyAuthenticated()/>