【发布时间】:2016-02-07 11:02:40
【问题描述】:
我正在通过一些示例应用程序学习 Spring Security。我遇到了一些问题。
我正在使用 Spring 4.2.2.RELEASE 和 Spring Security 4.0.2.RELEASE。 这是我的 Spring 安全上下文。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<context:component-scan base-package="com.mvc.sslspring.security" />
<security:authentication-manager id="authenticationManager">
<security:authentication-provider>
<security:user-service>
<security:user name="aa" password="aa" authorities="ROLE_USER" />
<security:user name="bb" password="bb"
authorities="ROLE_USER, ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<security:http realm="Protected API" use-expressions="true"
auto-config="false" create-session="stateless" entry-point-ref="restAuthenticationEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="restAuthenticationTokenProcessingFilter"
position="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/authenticate"
access="permitAll" />
<security:intercept-url pattern="/persons"
access="isAuthenticated() and hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/persons/*"
access="isAuthenticated() and hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/tasks"
access="isAuthenticated() and hasRole('ROLE_USER')" />
<security:intercept-url pattern="/tasks/*"
access="isAuthenticated() and hasRole('ROLE_USER')" />
<security:access-denied-handler ref="restAccessDeniedHandler" />
<security:csrf disabled="true" />
</security:http>
</beans>
(我已禁用 CSRF,因为它给 POSTMAN 客户端带来了一些问题。) 当用户输入用户名和密码并发送一个 JSON 时,我正在创建令牌,并在标头中使用该令牌,我正在访问资源。它对我来说很好,包括角色,除了几件事。
这是我的处理程序。
身份验证入口点处理程序
@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter out = response.getWriter();
out.print("{\"message\":\""+ authException.getMessage() + "\", \"access-denied\":true,\"cause\":\"SC_UNAUTHORIZED\"}");
out.flush();
out.close();
}
}
拒绝访问处理程序
@Component
public class RestAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
// response.sendError(HttpServletResponse.SC_FORBIDDEN,
// accessDeniedException.getMessage());
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
PrintWriter out = response.getWriter();
out.print("{\"message\":\"" + accessDeniedException.getMessage()
+ "\", \"access-denied\":true,\"cause\":\"SC_FORBIDDEN\"}");
out.flush();
out.close();
}
}
我的任务和人员控制器很少,它运行良好并返回 JSON。
首先我的用户身份验证有问题。
这是控制器中的身份验证方法
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public String authenticate(@RequestBody User user, HttpServletRequest request) throws Exception {
UserDetails userDetails = userService.loadUserByUsername(user.getUsername());
String tokenString = TokenUtils.createToken(user);
return tokenString;
}
User.java
import java.util.Collection;
import java.util.Collections;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
public class User implements UserDetails {
private String username;
private String password;
// getters and setters
// overridden methods
}
如果我输入正确的用户名和错误的密码,它会创建并返回令牌。如果我只输入错误的用户名,它会转到 RestAuthenticationEntryPoint 并用 JSON 消息发回 401 错误。
如何使用配置文件中的用户名和密码在控制器方法中验证用户身份?如果凭据错误,它应该使用自定义 JSON 发送 401 状态。
此外,如果任何控制器发生任何异常,我应该能够使用 JSON 消息发送 500 错误。有没有常见的方式来发送错误响应和处理身份验证?
我知道可以有身份验证失败处理程序。但是在 XML 配置中,哪里不提了。除了<security:form login/> 之外,我没有看到该选项,但我没有使用它。
【问题讨论】:
-
请一次一个问题。
标签: java rest spring-mvc spring-security