我尝试使用Spring的安全性获取当前登录的用户名,但Principal
对象返回空值。
这是我的REST控制器方法:
@RequestMapping("/getCurrentUser")
public User getCurrentUser(Principal principal) {
String username = principal.getName();
User user = new User();
if (null != username) {
user = userService.findByUsername(username);
}
return user;
}
注意:我正在运行Sping Boot 1.5.13和Spring安全4.2.6
- 这是我的安全配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private Environment env;
@Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/image/**",
"/book/**",
"/user/**"
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().cors().disable().httpBasic().and().authorizeRequests()
.antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
}
- 这是我的用户安全服务类:
@Service
public class UserSecurityService implements UserDetailsService {
private static final Logger LOG = LoggerFactory.getLogger(UserSecurityService.class);
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if(null == user) {
LOG.warn("Username {} not found", username);
throw new UsernameNotFoundException("Username "+username+" not found");
}
return user;
}
}
- 这是我的用户类:
@Entity
public class User implements UserDetails, Serializable {
private static final long serialVersionUID = 902783495L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="Id", nullable=false, updatable = false)
private Long id;
private String username;
private String password;
private String firstName;
private String lastName;
private String email;
private String phone;
private boolean enabled = true;
@OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private Set<UserRole> userRoles = new HashSet<>();
}
6条答案
按热度按时间jm2pwxwz1#
有多种方法可以做到这一点。
使用
SecurityContextHolder
从控制器使用
Principal
从
HttpServletRequest
开始cetgtptt2#
假设您的
User
类实现了UserDetails
,则可以从SecurityContextHolder
获取User
,而无需依赖注入。jxct1oxe3#
前一个答案应该可以很好地工作,如果使用spring web MVC控制器,您还可以使用springs默认方法参数解析器(
org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver
)将其自动注入到您的控制器中。控制器可以执行以下操作:
在上面的示例中,
MyPrincipal
扩展了org.springframework.security.authentication.AbstractAuthenticationToken
。然后,您可以将此主体传递到服务层。bvjxkvbb4#
正如@cosmos所问--您是否在使用Spring Security?
如果是,则应执行以下操作:
在您的SecurityConfig:
在您的控制器中:
vu8f3i0k5#
下面是用于获取用户主体的方法
ryhaxcpt6#
如果你正在使用keycloak,你可以用这种方式得到更多的细节