这段代码保护了所有的端点 - 但我相信你可以对其进行修改 :). Token使用Spring Boot Starter Security存储在Redis中,您需要定义自己的UserDetailsService
并将其传递给AuthenticationManagerBuilder
。
简而言之 - 复制粘贴EmbeddedRedisConfiguration
和SecurityConfig
,并将AuthenticationManagerBuilder
替换为您自己的逻辑。
HTTP:
请求token - 在请求头中发送基本的HTTP身份验证内容。 token将在响应头中返回。
http --print=hH -a user:password localhost:8080/v1/users
GET /v1/users HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Basic dXNlcjpwYXNzd29yZA==
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.3
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 4
Content-Type: text/plain;charset=UTF-8
Date: Fri, 06 May 2016 09:44:23 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
x-auth-token: cacf4a97-75fe-464d-b499-fcfacb31c8af
使用令牌的相同请求:
http --print=hH localhost:8080/v1/users 'x-auth-token: cacf4a97-75fe-464d-b499-fcfacb31c8af'
GET /v1/users HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/0.9.3
x-auth-token: cacf4a97-75fe-464d-b499-fcfacb31c8af
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 4
Content-Type: text/plain;charset=UTF-8
Date: Fri, 06 May 2016 09:44:58 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
如果您输入错误的用户名/密码或令牌,则会收到401错误。
JAVA
我将这些依赖项添加到build.gradle中。
compile("org.springframework.session:spring-session-data-redis:1.0.1.RELEASE")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-web")
compile("com.github.kstyrc:embedded-redis:0.6")
然后是 Redis 配置。
@Configuration
@EnableRedisHttpSession
public class EmbeddedRedisConfiguration {
private static RedisServer redisServer;
@Bean
public JedisConnectionFactory connectionFactory() throws IOException {
redisServer = new RedisServer(Protocol.DEFAULT_PORT);
redisServer.start();
return new JedisConnectionFactory();
}
@PreDestroy
public void destroy() {
redisServer.stop();
}
}
安全配置:
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(userService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.requestCache()
.requestCache(new NullRequestCache())
.and()
.httpBasic();
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
}
通常在教程中,您会发现
AuthenticationManagerBuilder
使用
inMemoryAuthentication
,但还有很多其他选择(LDAP等)。只需查看类定义即可。我正在使用需要
UserDetailsService
对象的
userDetailsService
。
最后,我的用户服务使用
CrudRepository
。
@Service
public class UserService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserAccount userAccount = userRepository.findByEmail(username);
if (userAccount == null) {
return null;
}
return new User(username, userAccount.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
}
}