Актуализирах услугата Spring REST на Рой Кларксън (https://github.com/royclarkson/spring-rest-service-oauth) с базирано на Jdbc хранилище на токени. Оригиналното изпълнение използва хранилище на токени в паметта. Успях да видя подробностите за потребителя в потребителския обект. От друга страна, след преминаване към хранилище на токени, базирано на Jdbc, всички полета в потребителския обект бяха празни. Изглежда по някакъв начин сигурността на Spring не е успяла да свърже токена за достъп с потребителя, под който получих токена, когато използвах Jdbc-базирано хранилище на токени.
Внедряване на хранилището за токени в паметта:
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
private TokenStore tokenStore = new InMemoryTokenStore();
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private ClientDetailsService clientDetailsService;
@Bean
public ClientDetailsService clientDetailsService() {
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
// @formatter:off
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
// @formatter:on
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.withClientDetails(clientDetailsService);
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
Крайната точка REST:
@RequestMapping("/greeting")
public Greeting greeting(@AuthenticationPrincipal User user) {
return new Greeting(counter.incrementAndGet(), String.format(template, user.getName()));
}
user.getName() връща името на потребителя, под който получих токена за достъп.
Внедряване на магазина за токени jdbc:
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends
AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private TokenStore tokenStore;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private ClientDetailsService clientDetailsService;
@Bean
public ClientDetailsService clientDetailsService() {
return new JdbcClientDetailsService(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
// @formatter:off
endpoints
.tokenStore(this.tokenStore)
.authenticationManager(this.authenticationManager)
.userDetailsService(userDetailsService);
// @formatter:on
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.withClientDetails(clientDetailsService);
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setSupportRefreshToken(true);
tokenServices.setTokenStore(this.tokenStore);
return tokenServices;
}
}
Крайната точка REST:
@RequestMapping("/greeting")
public Greeting greeting(@AuthenticationPrincipal User user) {
return new Greeting(counter.incrementAndGet(), String.format(template, user.getName()));
}
user.getName() връща нула.
CustomUserDetailsService
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
@Autowired
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByLogin(username);
if (user == null) {
throw new UsernameNotFoundException(String.format("User %s does not exist!", username));
}
return new UserRepositoryUserDetails(user);
}
private final static class UserRepositoryUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
private UserRepositoryUserDetails(User user) {
super(user);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
@Override
public String getUsername() {
return getLogin();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
}
Потребител
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@NotEmpty
private String name;
@NotEmpty
@Column(unique = true, nullable = false)
private String login;
@NotEmpty
private String password;
@NotEmpty
private String privilege;
@JsonIgnore
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
private Set<Role> roles = new HashSet<Role>();
public User() {
}
public User(User user) {
super();
this.id = user.getId();
this.name = user.getName();
this.login = user.getLogin();
this.password = user.getPassword();
this.roles = user.getRoles();
this.privilege = user.getPrivilege();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPrivilege() {return privilege; }
public void setPrivilege(String privilege) {this.privilege = privilege; }
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
CustomUserDetailsService
(което не сте показали)? - person Dave Syer   schedule 05.06.2015@Autowired
от поле, което е дефинирано като@Bean
в същия клас, изисква проблеми, така че предлагам да не правите това като начало. - person Dave Syer   schedule 06.06.2015