Spring 安全 4. JSON 具有自定义身份验证和授权的 REST
Spring security 4. JSON REST with custom authentication and authorization
我们正在开发 Spring 4 REST/JSON API 但我们需要自定义身份验证服务以针对第 3 方服务进行身份验证。
限制:我们不想要求用户username/password。我们正在使用 "cookie" 进行身份验证(与请求发起者一起发送)。我们需要在后台执行此身份验证过程。 (可能听起来很奇怪,但事实就是如此)。
我们可以使用注册自定义 authentication/authorization 请求过滤器来实现。但这使我们失去了我们计划在以后使用的 spring "authorization" 模块的功能。
所以我们到目前为止所做的,用我们自己的自定义 AuthenticationProvider 和 UserDetailsService[=38 编写自定义 WebSecurityConfigurerAdapter =] 但这些配置似乎不起作用。
申请没有进入AuthenticationProvider.authenticate
这是我们的配置。
AuthenticationProvider.java:
@Service
public class AuthenticationService implements AuthenticationProvider, UserDetailsService {
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
// DOESN'T ENTER THIS FUNCTION
// do authentication stuff
}
@Override
public boolean supports(Class<?> authentication) {
// JUST FOR TESTING
return true;
}
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// DOESN'T ENTER THIS METHOD
return null;
}
}
SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private AuthenticationService authService;
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/ignoredURL/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() //HTTP with Disable CSRF
.authorizeRequests()
.antMatchers("/api/XYZ/**").hasRole("ADMIN")
.anyRequest().authenticated();
// adding ".httpBasic()" automatically prompts user for username/password
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// THIS IS NOT TYPO, I use one service implements both interfaces.
auth.userDetailsService(authService);
auth.authenticationProvider(authService);
}
}
通过添加 2 个 classes(过滤器扩展 AbstractPreAuthenticatedProcessingFilter
和另一个 class CustomUser
实现 UserDetails
)修复,然后使我的 AuthenticaitonService
实现 spring UserDetailsService
以下是详细信息:
请看what this filter does and how it works
1- 创建 AbcFilter
扩展 spring AbstractPreAuthenticatedProcessingFilter
2- 覆盖 "getPreAuthenticatedPrincipal"。此方法提取了 cookie
值和 return 值。 (无论您 return 这里的对象是什么,您在 UserDetailsService.loadUserByUsername
中作为参数得到的都是什么。
3- 修改我的服务以实现 spring UserDetailsService
并在 loadUserByUsername
内部执行所有身份验证逻辑并在 CustomUser
对象中设置所有登录用户。那就return吧。
4- 只要请求匹配 /api/XYZ/**
,Spring 就会调用您的 CustomUser.getAuthorities
并尝试在那里找到 ADMIN
角色。
我们正在开发 Spring 4 REST/JSON API 但我们需要自定义身份验证服务以针对第 3 方服务进行身份验证。
限制:我们不想要求用户username/password。我们正在使用 "cookie" 进行身份验证(与请求发起者一起发送)。我们需要在后台执行此身份验证过程。 (可能听起来很奇怪,但事实就是如此)。
我们可以使用注册自定义 authentication/authorization 请求过滤器来实现。但这使我们失去了我们计划在以后使用的 spring "authorization" 模块的功能。
所以我们到目前为止所做的,用我们自己的自定义 AuthenticationProvider 和 UserDetailsService[=38 编写自定义 WebSecurityConfigurerAdapter =] 但这些配置似乎不起作用。
申请没有进入AuthenticationProvider.authenticate
这是我们的配置。
AuthenticationProvider.java:
@Service
public class AuthenticationService implements AuthenticationProvider, UserDetailsService {
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
// DOESN'T ENTER THIS FUNCTION
// do authentication stuff
}
@Override
public boolean supports(Class<?> authentication) {
// JUST FOR TESTING
return true;
}
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// DOESN'T ENTER THIS METHOD
return null;
}
}
SecurityConfig.java:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private AuthenticationService authService;
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/ignoredURL/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable() //HTTP with Disable CSRF
.authorizeRequests()
.antMatchers("/api/XYZ/**").hasRole("ADMIN")
.anyRequest().authenticated();
// adding ".httpBasic()" automatically prompts user for username/password
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// THIS IS NOT TYPO, I use one service implements both interfaces.
auth.userDetailsService(authService);
auth.authenticationProvider(authService);
}
}
通过添加 2 个 classes(过滤器扩展 AbstractPreAuthenticatedProcessingFilter
和另一个 class CustomUser
实现 UserDetails
)修复,然后使我的 AuthenticaitonService
实现 spring UserDetailsService
以下是详细信息:
请看what this filter does and how it works
1- 创建 AbcFilter
扩展 spring AbstractPreAuthenticatedProcessingFilter
2- 覆盖 "getPreAuthenticatedPrincipal"。此方法提取了 cookie
值和 return 值。 (无论您 return 这里的对象是什么,您在 UserDetailsService.loadUserByUsername
中作为参数得到的都是什么。
3- 修改我的服务以实现 spring UserDetailsService
并在 loadUserByUsername
内部执行所有身份验证逻辑并在 CustomUser
对象中设置所有登录用户。那就return吧。
4- 只要请求匹配 /api/XYZ/**
,Spring 就会调用您的 CustomUser.getAuthorities
并尝试在那里找到 ADMIN
角色。