我正在通过一些示例应用程序学习 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 时,我正在创建 token ,并在 header 中使用该 token ,我正在访问资源。它对我来说工作得很好,包括角色,除了一些事情。
这是我的处理程序。
身份验证入口点处理程序
@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();
}
}
我有几个用于任务和人员的 Controller ,它运行良好并返回 JSON。
首先,我在用户身份验证方面遇到问题。
这是 Controller 中的身份验证方法
@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
}
如果我输入正确的用户名和错误的密码,它将创建并返回 token 。如果我仅输入错误的用户名,它将转到 RestAuthenticationEntryPoint 并使用 JSON 消息发回 401 错误。
如何使用配置文件中的用户名和密码在 Controller 方法中对用户进行身份验证?如果凭据错误,它应该使用自定义 JSON 发送 401 状态。
此外,如果任何 Controller 中发生任何异常,我应该能够使用 JSON 消息发送 500 错误。有没有通用的方法来发送错误响应和处理身份验证?
我知道可能存在身份验证失败处理程序。但在XML配置中,哪里提呢。除了 <security:form login/>
之外,我没有看到该选项但我没有使用它。
最佳答案
有关使用用户名和密码在 Controller 方法中验证用户的问题的答案
。在 Controller 中,您使用自己的方法来获取用户身份验证详细信息,因此无法使用配置文件中的用户凭据来执行此操作因为您没有使用 Spring Securities 默认过滤器链。您可以使用默认设置来填充数据库中的这些用户,或更改 loadByUserName
的实现以硬编码这些用户。
关于java - Spring Security 4 - REST 身份验证失败和 Controller 异常处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33564422/