我们目前正在使用Spring Boot(1.2.6)编写中间件,以向我们的移动/ Web应用程序公开REST API。中间件没有数据库,并且得到了我们客户的一些远程服务的支持。
对于登录,我们将用户名/密码和一些参数(ip,用户代理等)发送到远程服务,并获取有关用户的一些信息(名称,上次登录,布尔更改密码标志等..),包括会话ID。我们写了一些bean,我们在相应的控制器中使用它:
packet
据我所知,Spring Security通常依赖于在控制器之前工作的servlet过滤器。例如,如果我在配置中启用formLogin,它会启用@RestController
@RequestMapping(value = "/user", produces = "application/json")
public final class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/login", method = RequestMethod.POST)
public LoginResponse login(@RequestBody final LoginRequest request, final HttpServletRequest servletRequest) {
final LoginResponse response = new LoginResponse();
final LoginServiceRequest serviceRequest = new LoginServiceRequest();
serviceRequest.setAdditionalRequestData(AdditionalRequestData.getInstance(servletRequest));
serviceRequest.setUsername(request.getUsername());
serviceRequest.setPassword(request.getPassword());
final LoginData serviceResponse = userService.login(serviceRequest);
response.setChangePassword(serviceResponse.isChangePassword());
// setting other params here...
return response;
}
}
,它根据我定义的UsernamePasswordAuthenticationFilter
bean处理身份验证。但是,在这种情况下我需要身份验证响应,并且我们发送以JSON编码的请求参数。所以过滤器似乎不适合我们。
相反,我创建了AuthenticationManager
和AuthenticationProvider
,并将上面的代码更改为以下内容:
AuthenticationToken
@RestController
@RequestMapping(value = "/user", produces = "application/json")
public final class UserController {
@Autowired
private AuthenticationManager auth;
@Autowired
private UserService userService;
@RequestMapping(value = "/login", method = RequestMethod.POST)
public LoginResponse login(@RequestBody final LoginRequest request,
final HttpServletRequest servletRequest) throws ServletException {
final LoginResponse response = new LoginResponse();
final Authentication authenticationToken = new CustomAuthenticationToken(
request.getUserId(),
request.getPassword(),
AdditionalRequestData.getInstance(servletRequest)
);
final LoginData loginData =
((CustomAuthenticationToken) auth.authenticate(authenticationToken)).getLoginData();
response.setChangePassword(loginData.isChangePassword());
// setting other params here...
return response;
}
}
负责调用AuthenticationProvider
方法,并将userService.login
设置为AuthenticationToken
。
这是我们的安全配置:
SecurityContext
这种manuel方法确实有效。我们还使用权限(ROLE_USER等..)来授予对不同端点的访问权。
有更好的解决方案吗?当我们这样做时,你认为我们失去了Spring Security的一些功能吗?