Spring Boot 프로젝트에 메서드 기반 보안을 추가하려면 어떻게 해야 합니까?
스프링 부트 프로젝트에 메서드 기반 보안을 추가하고 싶습니다.
내가 필요한 것은 단지 추가하는 것뿐인 것처럼 보였습니다.PermissionEvaluator
그리고.MethodSecurityExpressionHandler
콩, 주석 달기 내 것WebSecurityConfigurerAdapter
와 함께@EnableGlobalMethodSecurity(prePostEnabled = true)
및 사용 방법@PreAuthorize("isAuthenticated() and hasPermission(#param, 'somePermissionName')")
.
하지만 a를 추가한 후에.PermissionEvaluator
콩을
@Bean
public PermissionEvaluator permissionEvaluator() {
HelloPermissionEvaluator bean = new HelloPermissionEvaluator();
return bean;
}
나는 이해합니다.IllegalArgumentException
"기본 서블릿 처리를 구성하려면 서블릿 컨텍스트가 필요합니다."
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
at com.domain.simple.Application.main(Application.java:14)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
... 17 more
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:346)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7f296e3.CGLIB$defaultServletHandlerMapping$26(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7f296e3$$FastClassBySpringCGLIB$$48c20692.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$d7f296e3.defaultServletHandlerMapping(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 18 more
제가 웹에서 찾을 수 있는 것은 jUnit 테스트와 관련된 것뿐입니다.이 예외가 발생하는 이유는 무엇입니까?제가 무엇을 빠뜨리고 있나요?서블릿 컨텍스트 빈을 추가해야 합니까? 추가할 경우 어떻게 해야 합니까?
요구사항은 Gradle, Spring Boot 및 Java 구성(XML 구성 대신)최소 및 전체 소스는 다음과 같습니다.
어플.자바
package com.domain.simple;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {
public static void main(String[] args) throws Throwable {
SpringApplication.run(Application.class, args);
}
}
HelloController.java
package com.domain.simple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
Logger log = LoggerFactory.getLogger(HelloController.class);
// @PreAuthorize("isAuthenticated() and hasPermission(#param, 'somePermissionName')")
@RequestMapping(value = "/hello/{param}")
@ResponseBody
public String hello(@PathVariable("param") String param) {
log.info("hello(" + param + ") called");
return "Hello " + param;
}
}
HelloPermissionEvalator.java
package com.domain.simple;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
public class HelloPermissionEvaluator implements PermissionEvaluator {
Logger log = LoggerFactory.getLogger(HelloPermissionEvaluator.class);
@Override
public boolean hasPermission(Authentication authentication,
Object targetDomainObject, Object permission) {
log.info("hasPermission(Authentication, Object, Object) called");
return true;
}
@Override
public boolean hasPermission(Authentication authentication,
Serializable targetId, String targetType, Object permission) {
log.error("hasPermission(Authentication, Serializable, String, Object) called");
throw new RuntimeException("ID based permission evaluation currently not supported.");
}
}
WebSecurityConfig.java
package com.domain.simple;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@ComponentScan
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder)
throws Exception {
authManagerBuilder.inMemoryAuthentication().withUser("user")
.password("password").roles("USER");
}
// @Bean
// public MethodSecurityExpressionHandler expressionHandler() {
// DefaultMethodSecurityExpressionHandler bean = new DefaultMethodSecurityExpressionHandler();
// bean.setPermissionEvaluator(permissionEvaluator());
// return bean;
// }
// this causes an IllegalArgumentException ("A ServletContext is required to configure default servlet handling")
@Bean
public PermissionEvaluator permissionEvaluator() {
HelloPermissionEvaluator bean = new HelloPermissionEvaluator();
return bean;
}
}
빌드.그래들
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.2.RELEASE")
}
}
apply plugin: 'eclipse'
apply plugin: 'java'
apply plugin: 'spring-boot'
jar {
baseName = 'simple'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-snapshot" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-security")
}
task wrapper(type: Wrapper) {
gradleVersion = '1.12'
}
다음을 입력해 보십시오.PermissionEvaluator
별채로@Configuration
수업. 당신은 그것을 강제로 인스턴스화하는 것처럼 보입니다.ServletContext
준비되었습니다(스프링 보안 필터를 매우 일찍 생성해야 이러한 작업이 가능합니다).
유사한 문제가 발생했습니다.식 핸들러에서 사용자 지정 권한 평가자를 구성하려는 경우 다음과 같은 작업을 수행할 수 있습니다.
public class SecurityPermissionEvaluator implements PermissionEvaluator
{
//A is a spring managed bean on which permission evaluator depends
private A a;
@Autowired
public SecurityPermissionEvaluator(A a){
this.a = a;
}
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
return false;
}
}
then
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Autowired private A a;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
PermissionEvaluator permissionEvaluator = new SecurityPermissionEvaluator(a);
expressionHandler.setPermissionEvaluator(permissionEvaluator);
return expressionHandler;
}
}
권한 평가자를 명시적으로 사용하려면 위의 작업과 함께 Daveie가 제안한 대로 on config 파일에 권한 평가자 bean을 정의합니다.
언급URL : https://stackoverflow.com/questions/23638462/how-do-i-add-method-based-security-to-a-spring-boot-project
'programing' 카테고리의 다른 글
MySQL: 8.0.31 - 몇 개월 사용 후 ID 필드에 큰 차이(수천 개)가 발생합니다. (0) | 2023.06.28 |
---|---|
Git에서 현재 수정본이 무엇인지 어떻게 알 수 있습니까? (0) | 2023.06.28 |
Git는 서브모듈에 대한 커밋의 SHA1을 어디에 저장합니까? (0) | 2023.06.28 |
팬더에서 특정 조건이 충족되는 행 값 업데이트 (0) | 2023.06.28 |
'Basic' 특성 유형은 지속성 엔티티가 아니어야 합니다. (0) | 2023.06.28 |