스프링 MVC - 스프링 보안을 통해 사용자가 이미 로그인되어 있는지 확인?
저는 Spring MVC 어플이 있습니다.자체 사용자 지정 로그인 페이지를 사용합니다.로그인 성공 시 'LOGGED_'IN_USER' 개체가 HTTPS 세션에 배치됩니다.
인증된 사용자만 URL에 액세스할 수 있도록 하고 싶습니다.저는 웹 필터를 사용함으로써 이를 달성할 수 있다는 것을 알고 있습니다.그러나 이 부분은 Spring Security를 사용하여 수행하고 싶습니다(제 수표는 그대로 유지됩니다 - 'LOGGED_'를 찾아보세요).HTTPS 세션의 IN_USER' 개체(존재하는 경우 로그인).
현재 로그인 동작을 변경할 수 없습니다. 아직 Spring Security를 사용하지 않습니다.
Spring Security의 어떤 측면을 사용하여 단독으로 이 부분을 달성할 수 있습니까? 요청이 (로그인한 사용자로부터) 인증되었는지 확인합니다.
최소 4가지 방법이 있습니다.
스프링 보안 XML 구성
이것이 가장 쉬운 방법입니다.
<security:http auto-config="true" use-expressions="true" ...>
...
<security:intercept-url pattern="/forAll/**" access="permitAll" />
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
@보안 주석 기준
요망하는<global-method-security secured-annotations="enabled" />
@Secured("ROLE_ADMIN")
@RequestMapping(params = "onlyForAdmins")
public ModelAndView onlyForAdmins() {
....
}
@PreAuthorize 주석별
요망하는<global-method-security pre-post-annotations="enabled" />
@PreAuthorize("isAuthenticated()")
@RequestMapping(params = "onlyForAuthenticated")
public ModelAndView onlyForAuthenticatedUsers() {
....
}
프로그래밍적
SecurityContextHolder.getContext().getAuthentication() != null &&
SecurityContextHolder.getContext().getAuthentication().isAuthenticated() &&
//when Anonymous Authentication is enabled
!(SecurityContextHolder.getContext().getAuthentication()
instanceof AnonymousAuthenticationToken)
사용자 지정 표현식
기본 제공 식이 충분하지 않으면 확장할 수 있습니다.메서드 주석에 대한 SpEL 표현식을 확장하는 방법에 대해서는 다음과 같이 설명합니다.
- spring security expression language 주석에 사용할 사용자 지정 메서드를 만드는 방법
- http://bmchild.blogspot.de/2012/02/creating-custom-regex-spring-security.html
하지만 요격자에겐<security:intercept-url ... access="myCustomAuthenticatedExpression" />
개인 수업 문제를 다룰 필요가 없는 약간 다른 접근법이 있습니다. Spring Security 3.0용으로만 해봤지만, 3.1용으로도 가능했으면 좋겠습니다.
1.) 다음에서 확장되는 새 클래스를 생성해야 합니다.WebSecurityExpressionRoot
(Prefix Web이 중요한 부분입니다!)
public class MyCustomWebSecurityExpressionRoot
extends WebSecurityExpressionRoot {
public MyCustomWebSecurityExpressionRoot(Authentication a,
FilterInvocation f) {
super(a, f);
}
/** That method is the one that does the expression evaluation! */
public boolean myCustomAuthenticatedExpression() {
return super.request.getSession().getValue("myFlag") != null;
}
}
2.) 확장이 필요합니다.DefaultWebSecurityExpressionRootHandler
사용자 정의 표현 루트를 제공하는 핸들러가 있는 경우
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public EvaluationContext createEvaluationContext(Authentication a,
FilterInvocation f) {
StandardEvaluationContext ctx =
(StandardEvaluationContext) super.createEvaluationContext(a, f);
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
ctx.setRootObject(myRoot);
return ctx;
}
}
3.) 그런 다음 처리자를 투표자에게 등록해야 합니다.
<security:http use-expressions="true"
access-decision-manager-ref="httpAccessDecisionManager" ...>
...
<security:intercept-url pattern="/restricted/**"
access="myCustomAuthenticatedExpression" />
...
</security:http>
<bean id="httpAccessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg name="decisionVoters">
<list>
<ref bean="webExpressionVoter" />
</list>
</constructor-arg>
</bean>
<bean id="webExpressionVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler"
ref="myCustomWebSecurityExpressionHandler" />
</bean>
<bean id="myCustomWebSecurityExpressionHandler"
class="MyCustomWebSecurityExpressionHandler" />
스프링 시큐리티 3.1 업데이트
Spring Security 3.1 이후로 사용자 정의 표현을 구현하기가 좀 더 쉽습니다.더 이상 서브클래스를 할 필요가 없습니다.WebSecurityExpressionHandler
오버라이드(override)createEvaluationContext
. 대신 서브글라스 하나AbstractSecurityExpressionHandler<FilterInvocation>
또는 그 하위 클래스.DefaultWebSecurityExpressionHandler
e드)를 합니다.SecurityExpressionOperations createSecurityExpressionRoot(final Authentication a, final FilterInvocation f)
.
public class MyCustomWebSecurityExpressionHandler
extends DefaultWebSecurityExpressionHandler {
@Override
public SecurityExpressionOperations createSecurityExpressionRoot(
Authentication a,
FilterInvocation f) {
WebSecurityExpressionRoot myRoot =
new MyCustomWebSecurityExpressionRoot(a, f);
myRoot.setPermissionEvaluator(getPermissionEvaluator());
myRoot.setTrustResolver(this.trustResolver);
myRoot.setRoleHierarchy(getRoleHierarchy());
return myRoot;
}
}
다른 솔루션으로 클래스를 생성할 수 있습니다.
public class AuthenticationSystem {
public static boolean isLogged() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return null != authentication && !("anonymousUser").equals(authentication.getName());
}
// ...
// Any another methods, for example, logout
}
그런 다음 컨트롤러에서:
@Controller
@RequestMapping(value = "/promotion")
public final class PromotionController {
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public final String root() {
if (!AuthenticationSystem.isLogged()) return "login"; // or some logic
// some logic
return "promotion/index";
}
}
PS:
이전 해결책에 문제가 있는데, 이것은 Peter를 주석으로 설명합니다.
@Controller
@RequestMapping(value = "/promotion")
public final class PromotionController {
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public final String root(final Principal principal) {
if (null == principal) return "login"; // or some logic
// some logic
return "promotion/index";
}
}
이것이 당신이 이루고자 하는 것입니까?
<c:choose>
<c:when test="${pageContext.request.userPrincipal.authenticated}">Show something</c:when>
<c:otherwise>Show something else</c:otherwise>
</c:choose>
많은 인증 공급자가 UserDetails 개체를 주체로 만듭니다.
한 또 은 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ ΔΔΔ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Authentication.getPrincipal()
다의 한 입니다.UserDetails
됩니다; "anonymousUser"
(String
입니다.) 기본값입니다.
boolean isUserLoggedIn(){
return SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserDetails
}
WebSecurityConfigureAdapter를 확장하는 클래스를 만들고 일치하는 URL에 인증된 클래스를 추가할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/User/**").authenticated()
}
당신은 가도 좋습니다.
다음과 같은 엔드포인트를 만들었습니다.
@GetMapping("/api/authorize")
public boolean isUserLoggedIn() {
boolean isLoggedIn = false;
try {
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
isLoggedIn = true;
} catch (Exception e) {
isLoggedIn = false;
}
return isLoggedIn;
}
언급URL : https://stackoverflow.com/questions/12371770/spring-mvc-checking-if-user-is-already-logged-in-via-spring-security
'bestsource' 카테고리의 다른 글
계산된 속성과 폐쇄로 설정된 속성의 차이 (0) | 2023.09.06 |
---|---|
숫자(0-9)와 NO 문자만 사용할 수 있는 정규식 (0) | 2023.09.06 |
Mysql2:: 오류: 잠금을 시도할 때 교착 상태가 발견되었습니다. 트랜잭션을 다시 시작해 보십시오(Ruby on Rails). (0) | 2023.09.06 |
E: 'mysql-client' 패키지에 도커 구성을 사용하는 php-fpm 이미지 빌드에 설치 후보가 없습니다. (0) | 2023.09.06 |
스프링 세션 범위 콩(컨트롤러) 및 서비스에 대한 언급, 직렬화 측면 (0) | 2023.09.06 |