将Spring Security添加到现有的Spring Web App(使用JavaConfig)
作者:互联网
我有一个Spring MVC Rest Web App,我正在添加一层Spring Security.
当我经历Spring documentation时,我无法理解第3.1.3节的含义.我正在复制/粘贴以下部分的内容.
If we were using Spring elsewhere in our application we probably already had a WebApplicationInitializer that is loading our Spring Configuration. If we use the previous configuration we would get an error. Instead, we should register Spring Security with the existing ApplicationContext. For example, if we were using Spring MVC our SecurityWebApplicationInitializer would look something like the following:
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
This would simply only register the springSecurityFilterChain Filter for every URL in your application. After that we would ensure that SecurityConfig was loaded in our existing ApplicationInitializer. For example, if we were using Spring MVC it would be added in the getRootConfigClasses()
public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
// ... other overrides ...
}
所以,我已经有了以下内容
an Initializer.java (replacement of web.xml)
Config.java - Root Context
RestServlet.java - Servlet Context
这是我的Initializer.java
public class Initializer implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(Config.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(RestServlet.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
为了添加Spring Security层,我添加了以下内容
SecurityConfig.java
SecurityInitializer.java
SecurityConfig.java(这是在内存auth详细信息中测试使用).
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
SecurityInitializer.java
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer
{
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
现在,问题是我不确定如何执行这些步骤.如果我应该扩展AbstractSecurityWebApplicationInitializer或AbstractAnnotationConfigDispatcherServletInitializer,我不知道(基于文档的第3.2.3节).
另一个问题是这是一个REST应用程序.我没有任何返回jsps的控制器(我不想!).我的最终目标是使用OAuth2,生成并向前端webapp发出令牌(基于Angular)并以这种方式保护REST api.还可以在此基础上添加Facebook和Google登录.但我正在采取婴儿步骤与春季保安,我被困在这里.想知道是否有任何采取过这条道路的人都可以分享他们的智慧.
解决方法:
您可以将此注入为正常的@Configuration类,如下所示:
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
FooUserDetailsService fooUserDetailsService;
@Autowired
PasswordEncoder passwordEncoder;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.fooUserDetailsService).passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/signup").anonymous()
.antMatchers("/public/**").permitAll()
.antMatchers("/auth/**").permitAll()
.antMatchers("/api/**").hasRole("USER")
.antMatchers("/**").hasAnyRole("USER", "ADMIN")
.and()
.csrf().disable()
.formLogin()
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/auth").failureUrl("/auth")
.usernameParameter("j_username").passwordParameter("j_password")
.defaultSuccessUrl("/")
.and()
.logout()
.logoutUrl("/j_spring_security_logout")
.logoutSuccessUrl("/auth");
}
}
这里的路径只是示例,您可能需要重写它以满足您的需求,例如,如果这是您正在制作的纯REST API,则删除表单登录内容.
要加载它,您可以执行以下操作:
public class WebApplicationInitialiser implements WebApplicationInitializer {
private static Class<?>[] configurationClasses = new Class<?>[] {
WebSecurityConfiguration.class
};
}
使用createContext(configurationClasses)将类(假设您有多个)添加到上下文中;
我希望这可以帮到你.
标签:spring-social,spring,rest,spring-mvc,spring-security 来源: https://codeday.me/bug/20190831/1772884.html