问题描述
我知道保护 REST API 是广泛评论的话题,但我无法创建满足我的标准的小型原型(我需要确认这些标准是现实的).如何保护资源以及如何使用 Spring 安全性有很多选择,我需要澄清我的需求是否切合实际.
我的要求
- 基于令牌的身份验证器 - 用户将提供其凭据并获得唯一且有时间限制的访问令牌.我想在自己的实现中管理令牌创建、检查有效性、到期时间.
- 某些 REST 资源将是公开的 - 根本不需要进行身份验证,
- 只有拥有管理员权限的用户才能访问某些资源,
- 其他资源在所有用户授权后均可访问.
- 我不想使用基本身份验证
- Java 代码配置(非 XML)
当前状态
我的 REST API 运行良好,但现在我需要保护它.当我在寻找解决方案时,我创建了一个 javax.servlet.Filter
过滤器:
@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 抛出 IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;String accessToken = request.getHeader(AUTHORIZATION_TOKEN);账户 account = accountDao.find(accessToken);如果(帐户 == 空){抛出新的 UnauthorizedException();}chain.doFilter(req, res);}
但是这个带有 javax.servlet.filters
的解决方案不能按我的需要工作,因为使用 Spring servlet 通过
.@ControllerAdvice
进行异常处理存在问题调度员
我需要什么
我想知道这些标准是否现实并获得任何帮助,如何开始使用 Spring Security 保护 REST API.我阅读了很多教程(例如 Spring Data REST + Spring Security) 但都在非常基本的配置中工作 - 用户在配置中他们的凭据存储在内存中,我需要使用 DBMS 并创建自己的身份验证器.
请给我一些如何开始的想法.
实际上,对令牌身份验证使用过滤器 - 在这种情况下最好的方法
最终,您可以通过 Spring Data 创建 CRUD 来管理 Token 的属性,例如过期等.
这是我的令牌过滤器:http://pastebin.com/13WWpLq2
和令牌服务实现
某些 REST 资源将是公开的 - 根本不需要进行身份验证
这不是问题,您可以像这样通过 Spring 安全配置管理您的资源:.antMatchers("/rest/blabla/**").permitAll()
某些资源只有拥有管理员权限的用户才能访问,
看看 @Secured
对类的注解.示例:
@Controller@RequestMapping(value = "/adminservice")@Secured("ROLE_ADMIN")公共类 AdminServiceController {
其他资源在所有用户授权后即可访问.
回到Spring Security配置,你可以像这样配置你的url:
http.authorizeRequests().antMatchers("/openforall/**").permitAll().antMatchers("/alsoopen/**").permitAll().anyRequest().authenticated()
我不想使用基本身份验证
是的,通过令牌过滤器,您的用户将通过身份验证.
Java 代码配置(非 XML)
回到上面的话,看@EnableWebSecurity
.您的课程将是:
@Configuration@启用网络安全公共类 SecurityConfig 扩展了 WebSecurityConfigurerAdapter {}
您必须覆盖 configure 方法.下面的代码,只是举例,如何配置匹配器.它来自另一个项目.
@Overrideprotected void configure(HttpSecurity http) 抛出异常 {http.authorizeRequests().antMatchers("/assets/**").permitAll().anyRequest().authenticated().和().formLogin().usernameParameter("j_username").passwordParameter("j_password").loginPage("/登录").defaultSuccessUrl("/", true).successHandler(customAuthenticationSuccessHandler).permitAll().和().登出().logoutUrl("/注销").invalidateHttpSession(true).logoutSuccessUrl("/").deleteCookies("JSESSIONID").logoutRequestMatcher(new AntPathRequestMatcher("/logout")).和().csrf();}
I know that securing REST API is widely commented topic but I'm not able to create a small prototype that meets my criteria (and I need to confirm that these criteria are realistic). There are so many options how to secure resources and how work with Spring security, I need to clarify if my needs are realistic.
My requirements
- Token based authenticator - users will provide its credentials and get unique and time limited access token. I would like to manage token creation, checking validity, expiration in my own implementation.
- Some REST resources will be public - no need to authenticate at all,
- Some resources will be accessible only for users with administrator rights,
- Other resource will be accessible after authorization for all users.
- I don't want to use Basic authentication
- Java code configuration (not XML)
Current status
My REST API works very well, but now I need to secure it. When I was looking for a solution I created a javax.servlet.Filter
filter:
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
Account account = accountDao.find(accessToken);
if (account == null) {
throw new UnauthorizedException();
}
chain.doFilter(req, res);
}
But this solution with javax.servlet.filters
doesn't work as I need because there is an issue with exception handling via @ControllerAdvice
with Spring servlet dispatcher
.
What I need
I would like to know if these criteria are realistic and get any help, how to start securing REST API with Spring Security. I read many tutorials (e.g. Spring Data REST + Spring Security) but all work in very basic configuration - users with their credentials are stored in memory in configuration and I need to work with DBMS and create own authenticator.
Please give me some ideas how to start.
Actually, use Filter for token Auth - best way in this case
Eventually, you can create CRUD via Spring Data for managing Token's properties like to expire, etc.
Here is my token filter:http://pastebin.com/13WWpLq2
And Token Service Implementation
It's not a problem, you can manage your resources via Spring security config like this: .antMatchers("/rest/blabla/**").permitAll()
Take a look at @Secured
annotation to class. Example:
@Controller
@RequestMapping(value = "/adminservice")
@Secured("ROLE_ADMIN")
public class AdminServiceController {
Back to Spring Security configure, you can configure your url like this:
http
.authorizeRequests()
.antMatchers("/openforall/**").permitAll()
.antMatchers("/alsoopen/**").permitAll()
.anyRequest().authenticated()
Yep, via token filter, your users will be authenticated.
Back to the words above, look at @EnableWebSecurity
.Your class will be:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {}
You have to override the configure method. Code below, just for example, how to configure matchers. It's from another project.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/assets/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter("j_username")
.passwordParameter("j_password")
.loginPage("/login")
.defaultSuccessUrl("/", true)
.successHandler(customAuthenticationSuccessHandler)
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.invalidateHttpSession(true)
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and()
.csrf();
}
这篇关于如何使用 Spring Boot 和 Spring Security 保护 REST API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!