使用 Spring Security 启用对 @RestController 的访问
Posted
技术标签:
【中文标题】使用 Spring Security 启用对 @RestController 的访问【英文标题】:Enable access for @RestController using spring security 【发布时间】:2018-06-05 00:17:01 【问题描述】:我有一个使用 spring security basic auth 实现的项目。映射了四个访问角色。 "ADMIN"
映射到 "/admin/**"
我可以登录并访问WebContent/admin
文件夹中的所有html 资源。发布我使用@RestController
@RequestMapping("/admin/users")
创建了一些服务
问题是我无法访问任何宁静的服务。错误是404
。所有 restful 服务类都存在于 war 文件中。我确定存在一些配置问题。有什么想法吗?
我的代码spinet:
安全配置.java
package com.dev.portal.mvc.configs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.dev.portal.constants.UserRoles;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
CustomSuccessHandler customSuccessHandler;
@Autowired
AppUserDetailsService appUserDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(appUserDetailsService);
@Override
protected void configure(HttpSecurity http) throws Exception
String[] allRoles = UserRoles.ADMIN, UserRoles.ORG_ADMIN, UserRoles.CATALOG_ADMIN, UserRoles.DEVELOPER ;
http.authorizeRequests().antMatchers("/").hasAnyRole(allRoles)
.antMatchers("/admin/**").hasRole(UserRoles.ADMIN)
.antMatchers("/org_admin/**").hasRole(UserRoles.ORG_ADMIN)
.antMatchers("/catalog_admin/**").hasRole(UserRoles.CATALOG_ADMIN)
.antMatchers("/developer/**").hasRole(UserRoles.DEVELOPER)
.and().formLogin().successHandler(customSuccessHandler)
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll();
http.httpBasic();
http.csrf().disable();
MvcConfig.java
package com.dev.portal.mvc.configs;
import static com.mongodb.MongoClientOptions.builder;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import com.dev.portal.commons.CertificateHelper;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
@PropertySource( "classpath:mongodb.properties" )
@ComponentScan(basePackages = "com.dev.portal.services.orgadmin")
public class MvcConfig
private @Value("$db.ip") String db_ip;
private @Value("$db.port") String db_port;
private @Value("$db.name") String db_name;
private @Value("$db.user") String db_user;
private @Value("$db.password") String db_password;
private @Value("$db.admin") String db_admin;
@Bean
public CustomSuccessHandler getCustomSuccessHandler()
return new CustomSuccessHandler();
@Bean
public AppUserDetailsService getAppUserDetailsService()
return new AppUserDetailsService();
@Bean
public MongoTemplate getMongoTemplate()
MongoClient mongoClient =
new MongoClient(new ServerAddress(db_ip, Integer.parseInt(db_port)),
Arrays.asList(MongoCredential.createScramSha1Credential(db_user, db_admin,
db_password.toCharArray())),
builder().sslEnabled(true).socketFactory(CertificateHelper.validateCert(db_ip))
.sslInvalidHostNameAllowed(true).build());
return new MongoTemplate(new SimpleMongoDbFactory(mongoClient, db_name));
UserModelService.java
package com.dev.portal.services.orgadmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.dev.portal.dao.client.UserAuthDaoClient;
import com.dev.portal.models.UserAuthModel;
@RestController
@RequestMapping("/org_admin/user")
public class UserModelService
@Autowired
MongoTemplate mongoTemplate;
UserAuthDaoClient userAuthDaoClient = new UserAuthDaoClient(mongoTemplate);
@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
public UserAuthModel getUserAuthModelByUsername(@RequestParam String username)
return userAuthDaoClient.getUserAuthModelByUsername(username);
@RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json")
public UserAuthModel saveOrUpdateUserAuthModel(@RequestBody UserAuthModel userAuthModel)
return userAuthDaoClient.saveOrUpdateUserAuthModel(userAuthModel);
WebApplicationInitializer.java
package com.dev.portal.mvc.configs;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class WebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
public WebApplicationInitializer()
super(MvcConfig.class, SecurityConfig.class);
【问题讨论】:
【参考方案1】:我修改了MvcConfig.java
和WebApplicationInitializer.java
,如下所示,它表示工作正常。我仍在寻找另一种方法,因为我正在使用已弃用类的扩展。
MvcConfig.java
package com.dev.portal.mvc.configs;
import static com.mongodb.MongoClientOptions.builder;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.dev.portal.commons.CertificateHelper;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
@SuppressWarnings("deprecation")
@EnableWebMvc
@PropertySource( "classpath:mongodb.properties" )
@ComponentScan(basePackages = "com.dev.portal.services.**")
public class MvcConfig extends WebMvcConfigurerAdapter
private @Value("$db.ip") String db_ip;
private @Value("$db.port") String db_port;
private @Value("$db.name") String db_name;
private @Value("$db.user") String db_user;
private @Value("$db.password") String db_password;
private @Value("$db.admin") String db_admin;
@Bean
public CustomSuccessHandler getCustomSuccessHandler()
return new CustomSuccessHandler();
@Bean
public AppUserDetailsService getAppUserDetailsService()
return new AppUserDetailsService();
@Bean
public MongoTemplate getMongoTemplate()
MongoClient mongoClient =
new MongoClient(new ServerAddress(db_ip, Integer.parseInt(db_port)),
Arrays.asList(MongoCredential.createScramSha1Credential(db_user, db_admin,
db_password.toCharArray())),
builder().sslEnabled(true).socketFactory(CertificateHelper.validateCert(db_ip))
.sslInvalidHostNameAllowed(true).build());
return new MongoTemplate(new SimpleMongoDbFactory(mongoClient, db_name));
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
configurer.enable();
WebApplicationInitializer.java
package com.dev.portal.mvc.configs;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
public WebApplicationInitializer()
super(MvcConfig.class, SecurityConfig.class);
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext)
servletContext.addListener(new net.bull.javamelody.SessionListener());
servletContext.addFilter("CorsFilter", CORSFilter.class).addMappingForUrlPatterns(null, false, "/*");
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dev-portal-dispatcher",
new DispatcherServlet(new AnnotationConfigWebApplicationContext()));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
CORSFilter.java
package com.dev.portal.mvc.configs;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class CORSFilter implements Filter
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
chain.doFilter(req, res);
@Override
public void init(FilterConfig filterConfig)
@Override
public void destroy()
【讨论】:
以上是关于使用 Spring Security 启用对 @RestController 的访问的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Spring Security 中为 oauth/token 端点启用 CORS
如何在 Spring Boot 中使用 Spring Security 启用 CORS
如何在 Spring Boot 中在 Spring Security 级别启用 CORS [关闭]
如何使用 Spring MVC 和 Spring Security 为资源处理程序启用 HTTP 缓存