在没有身份验证的情况下从Spring控制器调用安全方法
我使用的是SpringBoot1.5.4、SpringDataREST和SpringSecurity。我创建了一个映射到不需要身份验证的特定路径的在没有身份验证的情况下从Spring控制器调用安全方法,spring,spring-mvc,spring-security,Spring,Spring Mvc,Spring Security,我使用的是SpringBoot1.5.4、SpringDataREST和SpringSecurity。我创建了一个映射到不需要身份验证的特定路径的@Controller,因为它从sms网关用于报告传入文本 所以我只需要创建一个控制器来读取这些参数,然后将文本保存到数据库中。这就是问题所在。为了存储数据,我使用安全的存储库,而在控制器中,我没有任何安全性(事实上,我不能要求提供者保护其调用) 我试图以编程方式设置身份验证上下文,但似乎不起作用: @Controller @RequestMappin
@Controller
,因为它从sms网关用于报告传入文本
所以我只需要创建一个控制器来读取这些参数,然后将文本保存到数据库中。这就是问题所在。为了存储数据,我使用安全的存储库,而在控制器中,我没有任何安全性(事实上,我不能要求提供者保护其调用)
我试图以编程方式设置身份验证上下文,但似乎不起作用:
@Controller
@RequestMapping(path = "/api/v1/inbound")
@Transactional
public class InboundSmsController {
private Logger log = LogManager.getLogger();
@RequestMapping(method = RequestMethod.POST, path = "/incomingSms", produces = "text/plain;charset=ISO-8859-1")
public ResponseEntity<?> incomingSms(@RequestParam(name = "Sender", required = true) String sender,
@RequestParam(name = "Destination", required = true) String destination,
@RequestParam(name = "Timestamp", required = true) String timestamp,
@RequestParam(name = "Body", required = true) String body) {
log.info(String.format("Text received from %s to %s at %s with content: %s", sender, destination, timestamp, body));
setupAuthentication();
try {
int transitsWithSameTextToday = transitCertificateRepository.countByTextAndDate(body, Instant.now()); //This is the method that raises an Auth exception
....
....
} finally(){
clearAuthentication();
}
SecurityContext context;
/**
* Set in the actual context the authentication for the system user
*/
private void setupAuthentication() {
context = SecurityContextHolder.createEmptyContext();
Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ADMIN");
Authentication authentication = new UsernamePasswordAuthenticationToken("system", "ROLE_ADMIN", authorities);
context.setAuthentication(authentication);
}
private void clearAuthentication() {
context.setAuthentication(null);
}
@控制器
@请求映射(路径=“/api/v1/inbound”)
@交易的
公共类内置控件{
专用记录器log=LogManager.getLogger();
@RequestMapping(method=RequestMethod.POST,path=“/incomingSms”,products=“text/plain;charset=ISO-8859-1”)
public ResponseEntity incomingSms(@RequestParam(name=“Sender”,required=true)字符串发送者,
@RequestParam(name=“Destination”,required=true)字符串目的地,
@RequestParam(name=“Timestamp”,required=true)字符串时间戳,
@RequestParam(name=“Body”,required=true)字符串体){
log.info(String.format(“从%s到%s在%s接收的文本,内容为:%s”,发件人、目的地、时间戳、正文));
setupAuthentication();
试试{
int transitsWithSameTextToday=TransitCertificatePository.countByTextAndDate(body,Instant.now());//这是引发身份验证异常的方法
....
....
}最后(){
clearAuthentication();
}
安全语境;
/**
*在实际上下文中设置系统用户的身份验证
*/
私有身份验证(){
context=SecurityContextHolder.createEmptyContext();
集合权限=AuthorityUtils.createAuthorityList(“角色\管理员”);
身份验证=新用户名PasswordAuthenticationToken(“系统”、“角色\管理员”、权限);
setAuthentication(身份验证);
}
私有void clear身份验证(){
setAuthentication(null);
}
方法countByTextAndDate
用@PreAuthorize(“isAuthenticated()”)注释
我也很惊讶设置Auth上下文时我发现了这个错误。我做错了什么吗?这是实现我目标的最佳方式吗
我不想用@PermitAll
注释我的方法,因为该方法也由Spring Data REST公开,我不希望任何人可以使用它。您正在寻找AccessDecisionManager
的RunAsManager。以下链接可以帮助您:
快乐的编码!!!只需像平常一样设置安全性(这样你就有了身份验证,一个匿名的身份验证,但仍然是授权),并为特定的一方编写一个安全规则。比如@PreAuthorize(“isAuthenticated()| | hasIpAddress()”
。