maven 기반 종합 프로젝트 구축 (4) - 사용자 정의 spring security 필터
1. 이전 편 을 바탕 으로 spring Security Simple - config. xml 파일 을 수정 합 니 다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http auto-config="true" access-denied-page="/403.jsp" >
<!-- -->
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<intercept-url pattern="/login.jsp" filters="none"/>
<intercept-url pattern="/loginError.do" filters="none"/>
<intercept-url pattern="/redirectAddUser.do" filters="none"/>
<intercept-url pattern="/common/**" filters="none"/>
<intercept-url pattern="/styles/**" filters="none"/>
<!-- -->
<form-login login-page="/login.jsp"
always-use-default-target="true"
default-target-url="/securityLogin.do"
authentication-failure-url="/loginError.do" />
<!-- -->
<logout logout-success-url="/login.jsp" invalidate-session="true" />
<!-- session -->
<session-management invalid-session-url="/sessionTimeout.do"
session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
<!-- -->
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
<http-basic/>
</http>
<!--
:
AuthenticationManager ,
AccessDecisionManager: ,
securityMetadataSource: ,
FilterSecurityInterceptor.setSecurityMetadataSource() FilterSecurityMetadataSource ,
SecurityMetadataSource
-->
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="accessDecisionManager" ref="accessDecisionManager" />
<beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />
</beans:bean>
<!-- , ,myUserDetailService -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myUserDetailService">
<password-encoder ref="md5Encoder">
<salt-source user-property="username"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
<!-- -->
<beans:bean id="md5Encoder" class="com.cpkf.notpad.security.impl.MD5EncoderImpl"/>
<!--
allowIfAllAbstainDecisions: ,false- decisionVoters ,
-->
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="allowIfAllAbstainDecisions" value="false" />
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="ROLE_" />
</beans:bean>
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</beans:list>
</beans:property>
</beans:bean>
<!-- -->
<beans:bean id="mySecurityMetadataSource" class="com.cpkf.notpad.security.impl.MySecurityMetadataSource" init-method="loadResourceDefine" />
</beans:beans>
우선, 우 리 는 필터 가 어떻게 작 동 하 는 지 이해 해 야 한다. 그것 은 주로 다음 세 부분 에 의존한다. AuthenticationManager 인증 관리자, 사용자 인증 입구 실현 AccessDecisionManager: 제어 정책 관리자 에 접근 하여 사용자 가 가지 고 있 는 역할 을 결정 합 니 다. security MetadataSource: 자원 소스 데이터 정의, 특정한 자원 이 어떤 역할 에 접근 할 수 있 는 지 정의 합 니 다. Google 이 사용 하 는 것 은 기본 필터 체인 의 org. spring from work. security. web. access. intercept. FilterSecurity Interceptor 필터 입 니 다. 다만 중요 한 인증 관리 와 자원 소스 데 이 터 를 자신의 것 으로 정의 합 니 다. AuthenticationManager 에 서 는 이전에 데 이 터 를 얻 었 던 세 가지 방식 을 사용 하지 않 습 니 다.사용자 정의 UserDetailService 로 로그 인 사용자 정 보 를 얻 고 인증 관리자 에 게 값 을 부여 합 니 다. security MetadataSource 에서 저 희 는 url 자원 라 이브 러 리 의 모든 url 과 일치 하 는 역할 을 초기 화 한 다음 에 모든 url 요청 과 초기 화 데 이 터 를 비교 하여 권한 수여 여 부 를 판단 합 니 다.
2、MyUserDetailServiceImpl
인터페이스 MyUserDetailService 를 뽑 았 습 니 다. 인터페이스 계승 org. springframework. security. core. userdetails. UserDetailsService
package com.cpkf.notpad.security.impl;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.cpkf.notpad.entity.Account;
import com.cpkf.notpad.entity.Resource;
import com.cpkf.notpad.entity.Role;
import com.cpkf.notpad.security.MyUserDetailService;
import com.cpkf.notpad.server.IAccountService;
/**
* Filename: MyUserDetailServiceImpl.java
* Description: UserDetailService ,
* Company:
* @author: Jiang.hu
* @version: 1.0
* Create at: May 26, 2011 4:23:27 PM
* modified:
*/
@Service("myUserDetailService")
public class MyUserDetailServiceImpl implements MyUserDetailService {
private static final Logger logger = Logger.getLogger(MyUserDetailServiceImpl.class);
@Autowired
private IAccountService accountService;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
//
Account account = accountService.getAccountByEmail(username);
if(account == null){
logger.info("Can not found any Account by given username:" + username);
throw new UsernameNotFoundException("Can not found any Account by given username:" + username);
}
//
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
if(!account.getRoles().isEmpty() && account.getRoles() != null){
Iterator<Role> roleIterator = account.getRoles().iterator();
while(roleIterator.hasNext()){
Role role = roleIterator.next();
GrantedAuthority grantedAuthority = new GrantedAuthorityImpl(role.getRoleName().toUpperCase());
System.out.println(" :" + role.getRoleName().toUpperCase());
authorities.add(grantedAuthority);
}
}
return new User(username, account.getPassWord(), true, true, true, true, authorities);
}
}
3、MySecurityMetadataSource
package com.cpkf.notpad.security.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;
import com.cpkf.notpad.entity.Resource;
import com.cpkf.notpad.entity.Role;
import com.cpkf.notpad.server.IResourceService;
/**
* Filename: MySecurityMetadataSource.java
* Description: ,
* Company:
* @author: Jiang.hu
* @version: 1.0
* Create at: May 26, 2011 5:04:50 PM
* modified:
*/
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
private static final Logger logger = Logger.getLogger(MySecurityMetadataSource.class);
@Autowired
private IResourceService resourceService;
private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
private UrlMatcher urlMatcher;
public MySecurityMetadataSource(){
urlMatcher = new AntUrlPathMatcher();
resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
// ,
// loadResourceDefine();
}
/*
* method name : loadResourceDefine
* description : ,
* @author : Jiang.Hu
* @param :
* @return : void
* Create at : May 27, 2011 2:38:26 PM
* modified :
*/
public void loadResourceDefine(){
List<Resource> resources = resourceService.getAllResources();
if(resources != null && !resources.isEmpty()){
for(Resource resource : resources){
Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
Iterator<Role> roleIterator = resource.getRoles().iterator();
while(roleIterator.hasNext()){
Role role = roleIterator.next();
ConfigAttribute configAttribute = new SecurityConfig(role.getRoleName());
configAttributes.add(configAttribute);
}
resourceMap.put(resource.getUrl(), configAttributes);
}
}
}
/*
* method name : getAttributes
* description : url , url
* @author : Jiang.Hu
* modified : leo , May 27, 2011
* @see : @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object)
*/
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
if((object == null) || !this.supports(object.getClass())){
logger.info("Object must be a FilterInvocation");
throw new IllegalArgumentException("Object must be a FilterInvocation");
}
Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
if(object instanceof FilterInvocation){
String requestUrl = ((FilterInvocation)object).getRequestUrl();
System.out.println(" url:" + requestUrl);
// url url,
if(resourceMap != null && !resourceMap.isEmpty()){
Iterator<String> iterator = resourceMap.keySet().iterator();
while(iterator.hasNext()){
String resourceUrl = iterator.next();
if(urlMatcher.pathMatchesUrl(resourceUrl, requestUrl)){
configAttributes.addAll(resourceMap.get(resourceUrl));
}
}
if(configAttributes.isEmpty()){
configAttributes.add(new SecurityConfig("nobody"));
}
for(ConfigAttribute configAttribute : configAttributes){
System.out.println(" url :" + configAttribute.toString());
}
return configAttributes;
}
}
return null;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return new ArrayList<ConfigAttribute>();
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
4. 이렇게 우리 는[email protected]예 를 들 어 사용자 역할 과 자원 바 인 딩 효 과 를 실현 합 니 다.
[email protected]사용자 보유 ROLEADMIN 역할, 로그 인 하여 "/ security Login. do" url 에 접근 할 때 resource 자원 라 이브 러 리 에 "/ security Login. do" 가 ROLE 없 으 면ADMIN 캐릭터, 이 사용 자 는 권한 이 없습니다. 403 페이지 로 넘 어가 야 합 니 다.
사용자 역할: ROLEADMIN
사용자 역할: ROLEGUEST
요청 url: / security Login. do
요청 url 일치 캐릭터: nobody
리 소스 자원 라 이브 러 리 에 "/ security Login. do" 가 ROLE 가 있다 면ADMIN 역할, 이 사용자 만 접근 가능
사용자 역할: ROLEADMIN
사용자 역할: ROLEGUEST
요청 url: / security Login. do
요청 url 매 칭 캐릭터: ROLEADMIN
5. 위의 기초 가 있 으 면 사용자 권한 관 리 를 설계 합 니 다.
우선 사용자 가 없 는 상태 에서 접근 할 url 입 니 다. 필터 검증 이 필요 없습니다.
<intercept-url pattern="/**" access="ROLE_ADMIN" />
<intercept-url pattern="/login.jsp" filters="none"/>
<intercept-url pattern="/redirectAddUser.do" filters="none"/>
<intercept-url pattern="/redirectRegist.do" filters="none"/>
<intercept-url pattern="/loginError.do" filters="none"/>
<intercept-url pattern="/sessionTimeout.do" filters="none"/>
<intercept-url pattern="/visualCode.do" filters="none"/>
<intercept-url pattern="/addAccount.do" filters="none"/>
<intercept-url pattern="/styles/**" filters="none"/>
<intercept-url pattern="/scripts/**" filters="none"/>
<intercept-url pattern="/images/**" filters="none"/>
그 다음 에 공공 url 자원 을 디자인 하고 모든 역할 에 부여 한다.
package com.cpkf.notpad.commons.constants;
/**
* Filename: PublicResourceEnum.java
* Description:
* home- (/* ,/** )
* owner-owner , eg
* Company:
* @author: Jiang.hu
* @version: 1.0
* Create at: May 30, 2011 10:53:27 AM
* modified:
*/
public enum PublicResourceEnum {
OWNER("owner","/owner/**"),HOME("home","/*");
private String publicResourceName;
private String publicResourcePath;
private PublicResourceEnum(String publicResourceName, String publicResourcePath) {
this.publicResourceName = publicResourceName;
this.publicResourcePath = publicResourcePath;
}
public String getPublicResourceName() {
return publicResourceName;
}
public String getPublicResourcePath() {
return publicResourcePath;
}
}
MySecurity MetadataSource 클래스 에 loadPublicResources 방법 을 추가 하고 초기 화 방법 loadResourceDefine 에서 호출 합 니 다.
public void loadPublicResources(){
List<Role> roles = roleService.getAllRoles();
for(PublicResourceEnum publicResourceEnum : PublicResourceEnum.values()){
Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
for(Role role : roles){
ConfigAttribute configAttribute = new SecurityConfig(role.getRoleName());
configAttributes.add(configAttribute);
}
resourceMap.put(publicResourceEnum.getPublicResourcePath(), configAttributes);
}
}
이렇게 되면 모든 가입 자 는 / * 1 급 자원 과 '/ owner / * 2 급 주소 에서 모든 자원 을 방문 할 수 있 고 다른 2 급 자원 은 resource 표 에서 지정 하여 해당 하 는 role 에 할당 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Windows에서 CodeArtifact(Maven)용 토큰을 자동으로 생성하는 방법CodeArtifact를 사용한 적이 있거나 사용할 계획이라면 매일 모든 Maven 프로젝트에서 수동으로 토큰(CODEARTIFACT_AUTH_TOKEN)을 생성해야 합니다. 이는 어려울 수 있으며 개발 속도를 늦출...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.