사용자 정의 Spring Security 권한 제어 관리 (실전 편)
실전 배경
배경 설명
프로젝트 에 서 는 url + httpmethod (restful 만족, 예 를 들 어:https://.../xxx/users/1일부 캐릭터 는 (HTTP GET) 만 볼 수 있 고, 추가 삭제 (POST, PUT, DELETE) 할 권리 가 없습니다.
시계 설계
혐의 를 피하 기 위해 서 는 사용 할 관건 적 인 필드 만 열거 하고, 나머지 는 스스로 머리 를 써 서 보충 하 시기 바 랍 니 다.
실현 전 분석
우 리 는 역방향 으로 생각 할 수 있다.
우리 의 수 요 를 실현 하려 면 가장 중요 한 단 계 는 Spring Security 의 AccessDecisionManager 로 하여 금 요청 한 url + httpmethod 가 우리 데이터베이스 의 설정 에 부합 되 는 지 판단 하 게 하 는 것 입 니 다.그러나 AccessDecisionManager 는 유사 한 수요 와 관련 된 Voter 를 판정 하지 않 았 기 때문에 우 리 는 Voter 의 실현 을 사용자 정의 해 야 한다 (기본적으로 등 록 된 Affirmative Based 의 전략 은 Voter 가 ACCESS GRANTED 표를 던 지면 통과 로 판정 하 는 것 도 우리 의 요구 에 부합 한다).voter 를 실현 한 후 중요 한 매개 변수 (Collection attributes) 가 있 습 니 다. ConfigAttribute 는 상황 에 따라 의미 가 다 릅 니 다.우 리 는 여기 서도 이 루어 져 야 한다.그러나 Collection attributes 인 자 는 Security MetadataSource 에서 얻 을 수 있 기 때문에 우 리 는 Security MetadataSource 를 실현 해 야 합 니 다.Spring Security 에서 현재 사용자 인증 정 보 는 Authentication 을 통 해 표 시 된 것 으로 알려 져 있 으 므 로 Authentication 에 사용자 (admin) 인 스 턴 스 를 포함 시 켜 야 합 니 다.Authentication 은 사용자 의 권한 정보 (Granted Authority) 도 포함 하고 있 기 때문에 Granted Authority 도 실현 해 야 합 니 다.
사고의 절 차 를 정리 하 다.
1. 사용자 정의 voter 구현.
2. 사용자 정의 ConfigAttribute 구현.
3. 사용자 정의 Security MetadataSource 구현.
4. Authentication 은 사용자 인 스 턴 스 를 포함 합 니 다.
5. 사용자 정의 Granted Authority 구현.
프로젝트 실전
1. 사용자 정의 GrantedAuthority 구현
UrlGrantedAuthority.java
public class UrlGrantedAuthority implements GrantedAuthority {
private final String httpMethod;
private final String url;
public UrlGrantedAuthority(String httpMethod, String url) {
this.httpMethod = httpMethod;
this.url = url;
}
@Override
public String getAuthority() {
return url;
}
public String getHttpMethod() {
return httpMethod;
}
public String getUrl() {
return url;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UrlGrantedAuthority target = (UrlGrantedAuthority) o;
if (httpMethod.equals(target.getHttpMethod()) && url.equals(target.getUrl())) return true;
return false;
}
@Override
public int hashCode() {
int result = httpMethod != null ? httpMethod.hashCode() : 0;
result = 31 * result + (url != null ? url.hashCode() : 0);
return result;
}
}
2. 사용자 정의 인증 사용자 인 스 턴 스
public class SystemUser implements UserDetails {
private final Admin admin;
private List menuOutputList;
private final List grantedAuthorities;
public SystemUser(Admin admin, List grantedPrivileges, List menuOutputList) {
this.admin = admin;
this.grantedAuthorities = grantedPrivileges.stream().map(it -> {
String method = it.getMethod() != null ? it.getMethod().getLabel() : null;
return new UrlGrantedAuthority(method, it.getUrl());
}).collect(Collectors.toList());
this.menuOutputList = menuOutputList;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return this.grantedAuthorities;
}
@Override
public String getPassword() {
return admin.getPassword();
}
@Override
public String getUsername() {
return null;
}
@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 Long getId() {
return admin.getId();
}
public Admin getAdmin() {
return admin;
}
public List getMenuOutputList() {
return menuOutputList;
}
public String getSalt() {
return admin.getSalt();
}
}
3. 사용자 정의 UrlConfigAttribute 구현
public class UrlConfigAttribute implements ConfigAttribute {
private final HttpServletRequest httpServletRequest;
public UrlConfigAttribute(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
@Override
public String getAttribute() {
return null;
}
public HttpServletRequest getHttpServletRequest() {
return httpServletRequest;
}
}
4. 사용자 정의 Security MetadataSource 구현
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Override
public Collection getAttributes(Object object) throws IllegalArgumentException {
final HttpServletRequest request = ((FilterInvocation) object).getRequest();
Set allAttributes = new HashSet<>();
ConfigAttribute configAttribute = new UrlConfigAttribute(request);
allAttributes.add(configAttribute);
return allAttributes;
}
@Override
public Collection getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
5. 사용자 정의 voter 구현
public class UrlMatchVoter implements AccessDecisionVoter
6. 사용자 정의 FilterSecurity Interceptor 구현
public class UrlFilterSecurityInterceptor extends FilterSecurityInterceptor {
public UrlFilterSecurityInterceptor() {
super();
}
@Override
public void init(FilterConfig arg0) throws ServletException {
super.init(arg0);
}
@Override
public void destroy() {
super.destroy();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
super.doFilter(request, response, chain);
}
@Override
public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
return super.getSecurityMetadataSource();
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return super.obtainSecurityMetadataSource();
}
@Override
public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource newSource) {
super.setSecurityMetadataSource(newSource);
}
@Override
public Class> getSecureObjectClass() {
return super.getSecureObjectClass();
}
@Override
public void invoke(FilterInvocation fi) throws IOException, ServletException {
super.invoke(fi);
}
@Override
public boolean isObserveOncePerRequest() {
return super.isObserveOncePerRequest();
}
@Override
public void setObserveOncePerRequest(boolean observeOncePerRequest) {
super.setObserveOncePerRequest(observeOncePerRequest);
}
}
프로필 키 설정
...
자, 이제 스프링 시 큐 리 티 권한 통제 여행 을 즐겨 보 세 요.
제 개인 블 로그 에 오신 것 을 환영 합 니 다:
www.javafan.cn
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.