활성 사용자의 User Details를 가져오는 방법
유저가 , 하고 있습니다.UserDetails
★★★★
User activeUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
log.debug(activeUser.getSomeCustomField());
잘 먹히긴 하는데, 이런 경우라면 봄이 더 편하게 살 수 있을 것 같아요.'먹다'를 수 있는 요?UserDetails
컨트롤러 또는 메서드에 자동 연결되어 있는지 확인합니다.
예를 들어 다음과 같습니다.
public ModelAndView someRequestHandler(Principal principal) { ... }
'아예'가 '아예'가 아니라 '아예'로 받는 게 아니라UsernamePasswordAuthenticationToken
, 나는 그것을 얻었다.UserDetails
대??
나는 우아한 해결책을 찾고 있다.좋은 생각 있어요?
프리암블:Spring-Security 3.2 이후 주석 기능이 향상되었습니다.@AuthenticationPrincipal
를 참조해 주세요.Spring-Security > = 3.2 를2た 、 Spring - Security >
다음 경우:
- 이전 버전의 Spring-Security를 사용합니다.
- 로그인이나 ID 등의 정보를 사용하여 데이터베이스에서 커스텀 사용자 개체를 로드해야 합니다.
HandlerMethodArgumentResolver
★★★★★★★★★★★★★★★★★」WebArgumentResolver
문제를 풀 도 있습니다.@AuthenticationPrincipal
★★★★★★★★★★★★★★★★★」AuthenticationPrincipalArgumentResolver
은, ( 「」 「」 「」 「」)에하고 있기 때문입니다.HandlerMethodArgumentResolver
)
후 계속 않으면 ""를 합니다.★★★★★★★★★★★★★★★★★,@AuthenticationPrincipal
Winch( Winch( Winch)@AuthenticationPrincipal
그리고 루카스 슈멜자이젠(답변).
(BTW: 제 답변은 좀 더 나이가 들었기 때문에 (2012년 1월) Lukas Schmelzeisen이 첫 번째로 등장한 것은@AuthenticationPrincipal
Spring Security 3.2 。
그러면 컨트롤러에서 를 사용할 수 있습니다.
public ModelAndView someRequestHandler(Principal principal) {
User activeUser = (User) ((Authentication) principal).getPrincipal();
...
}
한 번이라도 필요하시면 됩니다.그러나 컨트롤러에 인프라스트럭처의 상세 정보가 포함되어 있기 때문에 몇 배 이상 필요한 경우에는 일반적으로 프레임워크에 의해 숨겨져 있어야 합니다.
따라서 이러한 컨트롤러가 필요합니다.
public ModelAndView someRequestHandler(@ActiveUser User activeUser) {
...
}
따라서 구현만 하면 됩니다.방법이 있다.
Object resolveArgument(MethodParameter methodParameter,
NativeWebRequest webRequest)
throws Exception
파라미터하고, 「Web」( 「Web」)을 가 있습니다.User
method 인수(첫 번째 파라미터)를 책임지고 있다고 생각되는 경우.
Spring 3.1 이후라고 불리는 새로운 개념이 있습니다.Spring 3.1+ 를 사용하고 있는 경우는, Spring 3.1+ 를 사용해 주세요(이 답변의 다음 항에 설명되어 있습니다).
public class CurrentUserWebArgumentResolver implements WebArgumentResolver{
Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
if(methodParameter is for type User && methodParameter is annotated with @ActiveUser) {
Principal principal = webRequest.getUserPrincipal();
return (User) ((Authentication) principal).getPrincipal();
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
사용자 지정 주석을 정의해야 합니다. - 모든 사용자 인스턴스를 항상 보안 컨텍스트에서 가져와야 하지만 명령 개체가 아닌 경우 주석을 건너뛸 수 있습니다.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActiveUser {}
구성에서는 다음 항목만 추가하면 됩니다.
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
id="applicationConversionService">
<property name="customArgumentResolver">
<bean class="CurrentUserWebArgumentResolver"/>
</property>
</bean>
@ 참조: Spring MVC @Controller 메서드 인수를 커스터마이즈하는 방법을 학습합니다.
Spring 3.1을 사용하는 경우 WebArgumentResolver보다 HandlerMethodArgumentResolver를 권장합니다.Jay의 코멘트를 참조해 주세요.
도 마찬가지입니다.HandlerMethodArgumentResolver
3.1스프링 3.1+★
public class CurrentUserHandlerMethodArgumentResolver
implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return
methodParameter.getParameterAnnotation(ActiveUser.class) != null
&& methodParameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
if (this.supportsParameter(methodParameter)) {
Principal principal = webRequest.getUserPrincipal();
return (User) ((Authentication) principal).getPrincipal();
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
구성에서 이 항목을 추가해야 합니다.
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="CurrentUserHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
@'Spring MVC 3.1 HandlerMethodArgumentResolver 인터페이스 활용'을 참조하십시오.
스프링 보안 3.2 솔루션
Spring Security 3.2(Spring 3.2와 혼동하지 말 것)에는 자체 빌트인 솔루션이 있습니다.org.springframework.security.web.bind.annotation.AuthenticationPrincipal
이는 루카스 슈멜자이젠의 답변에 잘 나타나 있다.
그냥 쓰는 거야
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .AuthenticationPrincipalArgumentResolver
)org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver
: ": "" : "Activating" 중 @EnableWebMvcSecurity
이 을 는는에 mvc:argument-resolvers
3.1 한 것과 으로 - 스프링 3.1 솔루션에서 설명했습니다.
@Spring Security 3.2 레퍼런스, 11.2장 "@AuthenticationPrincipal" 참조
Spring-Security 4.0 솔루션
.2 4.에서는 Spring 3.2가 합니다.@AuthenticationPrincipal
★★★★★★★★★★★★★★★★★」AuthenticationPrincipalArgumentResolver
하다
org.springframework.security.core.annotation.AuthenticationPrincipal
org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver
(단, 오래된 패키지의 오래된 클래스는 아직 존재하므로 혼합하지 마십시오.)
그냥 쓰는 거야
import org.springframework.security.core.annotation.AuthenticationPrincipal;
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
하려면 , )을 해 둘 필요가 있습니다.org.springframework.security.web.method.annotation.
AuthenticationPrincipalArgumentResolver
": "activate" 에 @EnableWebMvcSecurity
이 을 는는에 mvc:argument-resolvers
3.1 한 것과 으로 - 스프링 3.1 솔루션에서 설명했습니다.
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
@Spring Security 5.0 레퍼런스, 39.3장 @AuthenticationPrincipal 참조
Ralphs Answer는 우아한 솔루션을 제공하지만, Spring Security 3.2에서는 더 이상 자신의 솔루션을 구현할 필요가 없습니다.ArgumentResolver
.
「 」가 UserDetails
행 implementCustomUser
이치노
@RequestMapping("/messages/inbox")
public ModelAndView findMessagesForUser(@AuthenticationPrincipal CustomUser customUser) {
// .. find messages for this User and return them...
}
Spring 보안 문서:@AuthenticationPrincipal을 참조하십시오.
스프링 되어 있기 MVC와는 Spring MVC를 합니다.스프링 보안은 다음을 반환합니다.Authentication
HttpServletRequest.getUserPrincipal()
디폴트로 메서드이기 때문에, 그것이 원금으로서 취득할 수 있는 것입니다. 해서 얻을 수 .UserDetails
으로부터 이의를 제기하다
UserDetails ud = ((Authentication)principal).getPrincipal()
은 사용하는에 따라 수에 따라 수 ).UsernamePasswordAuthenticationToken
)및 ('')Authentication
밀히 a a를 포함할 는 없습니다.UserDetails
또는 수 . 이치노력하다
" " " 를 호출하고 SecurityContextHolder
가장 우아한 접근법(이 방법을 따르겠습니다)은 고객의 요구와 사용자 객체 유형에 맞게 맞춤화된 자체 보안 컨텍스트액세서 인터페이스를 삽입하는 것입니다.관련 메서드를 사용하여 인터페이스를 만듭니다.을 사용하다
interface MySecurityAccessor {
MyUserDetails getCurrentUser();
// Other methods
}
다음 이 하려면 '하다'에 .SecurityContextHolder
표준 구현에서는 코드를 스프링 보안에서 완전히 분리할 수 있습니다.그런 다음 보안 정보 또는 현재 사용자의 정보에 액세스해야 하는 컨트롤러에 이 정보를 삽입합니다.
또 다른 주요 이점은 테스트용 고정 데이터로 쉽게 구현할 수 있다는 것입니다. 스레드 로케이션을 채우는 등의 걱정은 없습니다.
「 」의 실장HandlerInterceptor
「」, 「」, 「」, 「」, 「」, 「」,UserDetails
다음과 같이 모델이 있는 각 요청으로 이동합니다.
@Component
public class UserInterceptor implements HandlerInterceptor {
....other methods not shown....
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if(modelAndView != null){
modelAndView.addObject("user", (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal());
}
}
3.이 Spring Security 3.2 으로 즉시 할 수 .@AuthenticationPrincipal
「」가 .AuthenticationPrincipalArgumentResolver
.
그 용도의 간단한 예는 다음과 같습니다.
@Controller
public class MyController {
@RequestMapping("/user/current/show")
public String show(@AuthenticationPrincipal CustomUser customUser) {
// do something with CustomUser
return "view";
}
}
는 Custom User에서 .authentication.getPrincipal()
AuthenticationPrincipal 및 AuthenticationPrincipalArgumentResolver에 대응하는 Javadocs를 다음에 나타냅니다.
@Controller
public abstract class AbstractController {
@ModelAttribute("loggedUser")
public User getLoggedUser() {
return (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}
템플릿(예: JSP)에 권한이 있는 사용자가 필요한 경우
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<sec:authentication property="principal.yourCustomField"/>
와 함께
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security.version}</version>
</dependency>
다음과 같이 시험해 보십시오.[ Using Authentication Object from Spring ]를 사용하면 컨트롤러 방식에서 사용자 세부사항을 얻을 수 있습니다.다음 예에서는 인수와 함께 컨트롤러 방식으로 Authentication 객체를 전달하고 있습니다.사용자가 인증되면 Authentication Object에 세부 정보가 입력됩니다.
@GetMapping(value = "/mappingEndPoint") <ReturnType> methodName(Authentication auth) {
String userName = auth.getName();
return <ReturnType>;
}
를 취득하려면 , 「Active Users Details」를 합니다.@AuthenticationPrincipal
과 같이 - 음음 in in in in in in in in in in in in in in 。
public String function(@AuthenticationPrincipal UserDetailsImpl user,
Model model){
model.addAttribute("username",user.getName()); //this user object
contains user details
return "";
}
User Details Impl.java
import com.zoom.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class UserDetailsImpl implements UserDetails {
@Autowired
private User user;
public UserDetailsImpl(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("ADMIN");
return List.of(simpleGrantedAuthority);
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public String getRole(){
return user.getRole();
}
public String getName(){
return user.getUsername();
}
public User getUser(){
return user;
}
}
언급URL : https://stackoverflow.com/questions/8764545/how-to-get-active-users-userdetails
'programing' 카테고리의 다른 글
크기 뒤에 괄호를 사용해야 하는 이유와 시기 (0) | 2022.06.05 |
---|---|
범용 타입 T의 클래스인스턴스를 가져오려면 어떻게 해야 하나요? (0) | 2022.06.05 |
Java RegEx 메타 문자(.)와 일반 도트? (0) | 2022.06.05 |
vuex - 권장되지 않는 경우에도 직접 상태를 변경할 수 있습니까? (0) | 2022.06.05 |
Vuex를 사용하여 양식 입력 데이터를 변경할 수 없음 (0) | 2022.06.05 |