Java 带UserDetailsService实现的Spring安全性
我一直在尝试使用UserDetailsService设置Spring安全性。作为一个例子,我使用了。应用程序启动时没有任何异常,但身份验证不起作用。 目前,我为每个应用程序模块提供了一个核心SpringJava配置和SpringJava配置 核心Spring Java配置:Java 带UserDetailsService实现的Spring安全性,java,spring,spring-security,Java,Spring,Spring Security,我一直在尝试使用UserDetailsService设置Spring安全性。作为一个例子,我使用了。应用程序启动时没有任何异常,但身份验证不起作用。 目前,我为每个应用程序模块提供了一个核心SpringJava配置和SpringJava配置 核心Spring Java配置: public class AppInitializer implements WebApplicationInitializer { @Override @Autowired public void onStartup(S
public class AppInitializer implements WebApplicationInitializer {
@Override
@Autowired
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext context = getContext();
container.addListener(new ContextLoaderListener(context));
container.setInitParameter("spring.profiles.active", "dev"); //Workaround for NamingException
container.setInitParameter("spring.profiles.default", "dev"); //Workaround for NamingException
container.setInitParameter("spring.liveBeansView.mbeanDomain", "dev"); //Workaround for NamingException
ServletRegistration.Dynamic mainDispatcher =
container.addServlet("dispatcher", new DispatcherServlet(context));
ServletRegistration.Dynamic businessDispatcher =
container.addServlet("businessDispatcher", BusinessAppConfig.createDispatcherServlet(context));
ServletRegistration.Dynamic ppaDispatcher =
container.addServlet("ppaDispatcher", PpaAppConfig.createDispatcherServlet(context));
initDispatcher(mainDispatcher, 1, "/");
initDispatcher(businessDispatcher, 2, "/business");
initDispatcher(businessDispatcher, 3, "/ppa");
}
private void initDispatcher(ServletRegistration.Dynamic dispatcher, int loadOnStartUp, String mapping) {
if (dispatcher == null) {
System.out.println("Servlet" + dispatcher.getName() + " is already added");
} else {
dispatcher.setLoadOnStartup(loadOnStartUp);
dispatcher.addMapping(mapping);
}
}
public AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MvcConfiguration.class);
return context;
}
@Bean(name = "propertyConfigurer")
public PropertySourcesPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
placeholderConfigurer.setLocation(new ClassPathResource("common.properties"));
placeholderConfigurer.setLocation(new ClassPathResource("amazon.S3Storage.properties"));
placeholderConfigurer.setLocation(new ClassPathResource("local.storage.properties"));
placeholderConfigurer.setLocation(new ClassPathResource("log4j.properties"));
placeholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
return placeholderConfigurer;
}
}
业务模块的SpringJavaconf
@Configuration
public class BusinessAppConfig {
public static Servlet createDispatcherServlet(AnnotationConfigWebApplicationContext context) {
context.register(BusinessMvcConfig.class);
context.register(BusinessHibernateConfig.class);
context.register(BusinessSecurityConfig.class);
return new DispatcherServlet(context);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class BusinessSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(getPasswordEncoder());
return authProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().
and().formLogin().permitAll().
and().logout().permitAll();
}
@Bean(name = "passwordEncoder")
public PasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder(11);
}
}
业务模块的Spring安全java配置
@Configuration
public class BusinessAppConfig {
public static Servlet createDispatcherServlet(AnnotationConfigWebApplicationContext context) {
context.register(BusinessMvcConfig.class);
context.register(BusinessHibernateConfig.class);
context.register(BusinessSecurityConfig.class);
return new DispatcherServlet(context);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class BusinessSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Autowired
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(getPasswordEncoder());
return authProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().
and().formLogin().permitAll().
and().logout().permitAll();
}
@Bean(name = "passwordEncoder")
public PasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder(11);
}
}
UserDetailsService实现
@Service
public class UserDetailsServiceImpl extends BaseServiceImpl<User, UserRepository<User>> implements UserDetailsService, UserService {
@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
User user = dao.findUserByLogin(login);
if (user == null) {
throw new UsernameNotFoundException(login);
}
return new UserPrincipal(user);
}
}
及
及
那么,这个配置有什么问题吗?所以,我在配置Spring安全性时犯了几个错误。 查找这些bug有助于分析调试消息 更改前请求的调试消息:
2018-06-03 00:14:26 DEBUG DispatcherServlet:891 - DispatcherServlet with name 'dispatcher' processing GET request for [/]
2018-06-03 00:14:26 DEBUG RequestMappingHandlerMapping:312 - Looking up handler method for path /
2018-06-03 00:14:26 DEBUG RequestMappingHandlerMapping:319 - Returning handler method [public java.lang.String business.controller.HomePageController.getHomePage(java.util.Map<java.lang.String, java.lang.Object>)]
2018-06-03 00:14:26 DEBUG DefaultListableBeanFactory:254 - Returning cached instance of singleton bean 'homePageController'
2018-06-03 00:14:26 DEBUG DispatcherServlet:979 - Last-Modified value for [/] is: -1
2018-06-03 00:14:26 DEBUG DispatcherServlet:1319 - Rendering view [org.springframework.web.servlet.view.JstlView: name 'index'; URL [/WEB-INF/views/index.jsp]] in DispatcherServlet with name 'dispatcher'
2018-06-03 00:14:26 DEBUG DefaultListableBeanFactory:254 - Returning cached instance of singleton bean 'requestDataValueProcessor'
2018-06-03 00:14:26 DEBUG JstlView:168 - Forwarding to resource [/WEB-INF/views/index.jsp] in InternalResourceView 'index'
2018-06-03 00:14:26 DEBUG DispatcherServlet:1000 - Successfully completed request
2018-06-03 00:14:31 DEBUG DispatcherServlet:891 - DispatcherServlet with name 'dispatcher' processing GET request for [/business/project/new]
2018-06-03 00:14:31 DEBUG RequestMappingHandlerMapping:312 - Looking up handler method for path /business/project/new
2018-06-03 00:14:31 DEBUG RequestMappingHandlerMapping:319 - Returning handler method [public java.lang.String business.controller.ProjectController.newProject(org.springframework.ui.Model) throws java.lang.Exception]
2018-06-03 00:14:31 DEBUG DefaultListableBeanFactory:254 - Returning cached instance of singleton bean 'projectController'
2018-06-03 00:14:31 DEBUG DispatcherServlet:979 - Last-Modified value for [/business/project/new] is: -1
路径更改后的调试:
2018-06-03 20:33:43 DEBUG DispatcherServlet:891 - DispatcherServlet with name 'businessDispatcher' processing GET request for [/business/]
2018-06-03 20:33:43 DEBUG RequestMappingHandlerMapping:312 - Looking up handler method for path /
2018-06-03 20:33:43 DEBUG RequestMappingHandlerMapping:319 - Returning handler method [public java.lang.String business.controller.HomePageController.getHomePage(java.util.Map<java.lang.String, java.lang.Object>)]
2018-06-03 20:33:43 DEBUG DefaultListableBeanFactory:254 - Returning cached instance of singleton bean 'homePageController'
2018-06-03 20:33:43 DEBUG DispatcherServlet:979 - Last-Modified value for [/business/] is: -1
2018-06-03 20:33:43 DEBUG DispatcherServlet:1319 - Rendering view [org.springframework.web.servlet.view.JstlView: name 'index'; URL [/WEB-INF/views/index.jsp]] in DispatcherServlet with name 'businessDispatcher'
2018-06-03 20:33:43 DEBUG DefaultListableBeanFactory:254 - Returning cached instance of singleton bean 'requestDataValueProcessor'
2018-06-03 20:33:43 DEBUG JstlView:168 - Forwarding to resource [/WEB-INF/views/index.jsp] in InternalResourceView 'index'
2018-06-03 20:33:43 DEBUG DispatcherServlet:1000 - Successfully completed request
到
要保护方法不受浏览器地址行中直接键入URL的影响,需要进行以下更改:
检查
securedEnabled=true,
prespenabled=true
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class BusinessSecurityConfig extends WebSecurityConfigurerAdapter {
@Controller
@RequestMapping(value = "/project")
@PreAuthorize("isAuthenticated()")
public class ProjectController {
每个控制器或特定方法应通过@PreAuthorize
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class BusinessSecurityConfig extends WebSecurityConfigurerAdapter {
@Controller
@RequestMapping(value = "/project")
@PreAuthorize("isAuthenticated()")
public class ProjectController {
或
注意:如果未经授权的用户试图访问受保护的方法,则将传播AuthenticationCredentialsNotFoundException
要处理此类异常,请参见,您应该包括一些日志,以查看实际发生的情况,仅说明它不起作用,很难找到我打开调试模式并遇到两个异常的原因。我将它们附在主题的底部,如果最新的更改已提交给分支机构,则可能会有所帮助
@Controller
@RequestMapping(value = "/project")
public class ProjectController {
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class BusinessSecurityConfig extends WebSecurityConfigurerAdapter {
@Controller
@RequestMapping(value = "/project")
@PreAuthorize("isAuthenticated()")
public class ProjectController {
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = "/new", method = RequestMethod.GET)
public String newProject (Model model) throws Exception {
model.addAttribute(new Project());
return "project/new";
}