我试图使用Spring的安全性获取当前登录的用户名,但Principal
对象返回null。
这是我的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;
}
注意:我正在运行Spring boot 1.5.13和spring security 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<>();
}
答案 0 :(得分:1)
假设您的User
类实现UserDetails
,您可以从User
获取SecurityContextHolder
而无需依赖注入。
public User getCurrentUser(Principal principal) {
return ((User) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal());
}
答案 1 :(得分:1)
之前的答案应该可行,
如果使用spring web MVC控制器,你也可以使用spring默认方法参数解析器(@RestController
public class AcceptConnectionController {
@PostMapping(value = "/")
public void controllerMethod(@AuthenticationPrincipal final MyPrincipal user) {
//...
}
}
)
控制器可以:
MyPrincipal
在上面的示例中,org.springframework.security.authentication.AbstractAuthenticationToken
扩展了from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
class Main(App):
def build(self):
base = Builder.load_file("main.kv")
base.ids.img.width = Window.width
base.ids.img.height = Window.height
return base
然后,您可以将此主体传递给服务层。
答案 2 :(得分:0)
按照@cosmos的要求-您是否正在使用Spring Security?
如果是,则应执行以下操作:
在您的SecurityConfig中:
@Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
在您的控制器中:
private String getPrincipal() {
String userName = null;
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
userName = ((UserDetails) principal).getUsername();
} else {
userName = principal.toString();
}
return userName;
}
答案 3 :(得分:0)
有多种方法可以做到这一点。
使用SecurityContextHolder
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
使用控制器中的Principal
@RequestMapping(value = "/myusername", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
来自HttpServletRequest
@RequestMapping(value = "/myusername", method = RequestMethod.GET)
@ResponseBody
public String getUsername(HttpServletRequest req) {
return req.getUserPrincipal.getName();
}
答案 4 :(得分:0)
这是一种用于获取用户主体的方法
@PutMapping(value = "/{userId}")
public ResponseEntity<?> updateUser(@Valid @RequestBody UserPutRequest updateRequest, @PathVariable String userId,
Authentication authentication) {
Optional<UserObject> userOptional = userRepository.findById(userId);
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
UserObject currentUser = userRepository.findByEmail(userPrincipal.getEmail());
}