RESTful 授权检查
RESTful Authorization check
我有一个 RESTful 网络应用程序,想要实现基于令牌的身份验证。我能够使用过滤器 class 发出令牌拦截请求,如下所示:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
JpaConfiguration jpaConfiguration;
@Override
protected void configure(HttpSecurity http) throws Exception {
// disable caching
http.headers().cacheControl();
http.csrf().disable() // disable csrf for our requests.
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and()
// Here the login requests is filtered
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
// Much probably here I have to filter other requests to check the presence of JWT in header,
// here i just add a commented block with teh name of the Filter
//.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}
}
JWTLoginFilter class 看起来像这样:
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(String url, AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
ServletInputStream inputStream = httpServletRequest.getInputStream();
httpServletRequest.getCharacterEncoding();
ObjectMapper mapper = new ObjectMapper();
AccountCredentials credentials = mapper.readValue(inputStream, AccountCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
String name = authentication.getName();
tokenAuthenticationService.addAuthentication(response, name);
}
}
哪个 class 应该扩展 JWTAuthenticationFilter
以拦截请求?
还是AbstractAuthenticationProcessingFilter
class吗?
是否有更好的方法来开发基于令牌的身份验证?
我不明白为什么要使用 JWTLoginFilter。我正在做一个开发由 OAuth2 保护的 RESTful 的项目。总的来说,请求者必须将访问令牌与 REST API 一起传递以进行授权。
以下例子可以作为参考
@Configuration
@EnableResourceServer
public class Oauth2AuthConfiguration implements ResourceServerConfigurer {
@Autowired
private OAuth2RemoteTokenServices tokenServices;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices);
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.exceptionHandling()
.accessDeniedHandler(new PPDAccessDeniedHandler())
.authenticationEntryPoint(new PPDAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers(POST, "/api/test").hasAuthority("PARTNER");
}
}
OAuth2RemoteTokenServices.java
public class OAuth2RemoteTokenServices implements ResourceServerTokenServices{
//implement how you can validate token here
// reference: org.springframework.security.oauth2.provider.token.RemoteTokenServices
}
所以我终于找到了解决办法:
public class JWTAuthenticationFilter extends GenericFilterBean implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try{
...
SecurityContextHolder.getContext().setAuthentication(token);
chain.doFilter(servletRequest, response);
}catch(Exception e){
e.printStackTrace();
}
}
}
JWTAuthenticationFilter
扩展了 GenericFilterBean
class 并且必须实现 spring 安全过滤器,方法 doFilter 可以解决问题。
注意:您必须从 FilterChain
class 调用 doFilter
方法,否则您是新来的终点,我对此很生气。
我有一个 RESTful 网络应用程序,想要实现基于令牌的身份验证。我能够使用过滤器 class 发出令牌拦截请求,如下所示:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
JpaConfiguration jpaConfiguration;
@Override
protected void configure(HttpSecurity http) throws Exception {
// disable caching
http.headers().cacheControl();
http.csrf().disable() // disable csrf for our requests.
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and()
// Here the login requests is filtered
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
// Much probably here I have to filter other requests to check the presence of JWT in header,
// here i just add a commented block with teh name of the Filter
//.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
;
}
}
JWTLoginFilter class 看起来像这样:
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(String url, AuthenticationManager authenticationManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authenticationManager);
tokenAuthenticationService = new TokenAuthenticationService();
}
@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws AuthenticationException, IOException, ServletException {
ServletInputStream inputStream = httpServletRequest.getInputStream();
httpServletRequest.getCharacterEncoding();
ObjectMapper mapper = new ObjectMapper();
AccountCredentials credentials = mapper.readValue(inputStream, AccountCredentials.class);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
return getAuthenticationManager().authenticate(token);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException {
String name = authentication.getName();
tokenAuthenticationService.addAuthentication(response, name);
}
}
哪个 class 应该扩展 JWTAuthenticationFilter
以拦截请求?
还是AbstractAuthenticationProcessingFilter
class吗?
是否有更好的方法来开发基于令牌的身份验证?
我不明白为什么要使用 JWTLoginFilter。我正在做一个开发由 OAuth2 保护的 RESTful 的项目。总的来说,请求者必须将访问令牌与 REST API 一起传递以进行授权。
以下例子可以作为参考
@Configuration
@EnableResourceServer
public class Oauth2AuthConfiguration implements ResourceServerConfigurer {
@Autowired
private OAuth2RemoteTokenServices tokenServices;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenServices(tokenServices);
}
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.exceptionHandling()
.accessDeniedHandler(new PPDAccessDeniedHandler())
.authenticationEntryPoint(new PPDAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers(POST, "/api/test").hasAuthority("PARTNER");
}
}
OAuth2RemoteTokenServices.java
public class OAuth2RemoteTokenServices implements ResourceServerTokenServices{
//implement how you can validate token here
// reference: org.springframework.security.oauth2.provider.token.RemoteTokenServices
}
所以我终于找到了解决办法:
public class JWTAuthenticationFilter extends GenericFilterBean implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try{
...
SecurityContextHolder.getContext().setAuthentication(token);
chain.doFilter(servletRequest, response);
}catch(Exception e){
e.printStackTrace();
}
}
}
JWTAuthenticationFilter
扩展了 GenericFilterBean
class 并且必须实现 spring 安全过滤器,方法 doFilter 可以解决问题。
注意:您必须从 FilterChain
class 调用 doFilter
方法,否则您是新来的终点,我对此很生气。