如何使用java和xml配置在Spring Security中配置jdbc身份验证管理器? [英] How to configure jdbc authentication manager in spring security using java and xml configuration?

查看:161
本文介绍了如何使用java和xml配置在Spring Security中配置jdbc身份验证管理器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Spring安全性来保护Spring Boot Web应用程序的安全,但是在配置身份验证管理器时,我与级联方​​法感到困惑.目前,我正在使用内存数据库,该数据库具有表用户以及填充有数据的权限.

I’m trying to secure spring boot web application using spring security, but I’m getting confused with cascading methods while configuring authentication manager. Currently, I’m using in-memory database, which has tables users, authorities populated with data.

任何人都可以解释这种用例配置身份验证机制的简便方法吗?

Can anyone please explain easier way to configure authentication mechanism for this use case?

推荐答案

为需要此服务的其他人造福.

For the benefit of others who is in need of this.

要实现jdbcAuthentication,您需要向数据库表中写入两个查询
Query1: usersByUsernameQuery (设置用于根据用户名查找用户的查询.)
Query2: authoritiesByUsernameQuery (设置用于根据用户名查找用户权限的查询.)

For implementing jdbcAuthentication you need to write two queries to your database tables
Query1: usersByUsernameQuery (Sets the query to be used for finding a user by their username.)
Query2: authoritiesByUsernameQuery (Sets the query to be used for finding a user's authorities by their username.)

它可能是java配置或xml配置,您所需要做的就是
1.创建数据源
2.通过注入数据源依赖性并配置usersByUsernameQuery和AuthorityByUsernameQuery在AuthenticationManagerBuilder中配置jdbc身份验证. 3.配置HttpSecurity.下面提供了详细信息和默认值
-----为这些URL的

Either it may be java configuration or xml configuration, all you need to do is
1. Create datasource
2. Configure jdbc authentication in AuthenticationManagerBuilder by injecting datasource dependency and configuring usersByUsernameQuery and authoritiesByUsernameQuery.
3. Configure HttpSecurity. Details and defaults given below
----- Configure intercept-url pattern and authorization for those url's

Default role of unauthenticated user = ROLE_ANONYMOUS

-----配置表单登录,以避免出现默认的登录屏幕和下面给出的默认行为.

----- Configure form login to avoid default login screen and default behavior given below.

login-page        = "/login" with HTTP get
usernameParameter = "username"
passwordParameter = "password"
failureUrl        = "/login?error"
loginProcessingUrl= "/login" with HTTP post
successUrl        = "/"

-----配置注销以覆盖默认行为.

----- Configure logout to override default behavior.

logoutUrl        = "/logout"
logoutSuccessUrl = "/login?logout"

-----配置会话管理以覆盖默认行为

----- Configure session management to override default behavior

expiredUrl         = "/login?expired"
invalidate-session = true //you can set false and use delete-cookies="JSESSIONID"
maximumSessions    = The default is to allow any number of sessions for a users.

Javaconfig方式

如果这不足以从我的github存储库下载. 使用Java配置工作的Spring Security副本

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
{

    public DataSource dataSource()
    {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/springmvc");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setInitialSize(2);
        dataSource.setMaxActive(5);

        return dataSource;
    }


    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
                .authoritiesByUsernameQuery(
                        "select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId  where username = ?");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        http
        .authorizeRequests()
            .antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
            .antMatchers("/config/*", "/app/admin/*")
            .hasRole("ADMIN")
            .antMatchers("/app/user/*")
            .hasAnyRole("ADMIN", "USER")
        .and().exceptionHandling()
            .accessDeniedPage("/403")
        .and().formLogin()
            .loginPage("/login")
            .usernameParameter("userName").passwordParameter("password")
            .defaultSuccessUrl("/app/user/dashboard")
            .failureUrl("/login?error=true")
        .and().logout()
            .logoutSuccessHandler(new CustomLogoutSuccessHandler())
            .invalidateHttpSession(true)
        .and()
            .csrf()
                .disable();

        http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
    }

    @Bean
    public PasswordEncoder passwordEncoder() 
    {
        return new BCryptPasswordEncoder();
    }

}

XML配置方式(不适用于Spring Boot)

如果这不足以从我的github存储库下载. 使用XML配置工作的Spring安全副本

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"  
    xmlns:beans="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans.xsd  
    http://www.springframework.org/schema/security  
    http://www.springframework.org/schema/security/spring-security.xsd">  

    <http auto-config="true" use-expressions="true" create-session="ifRequired">
        <csrf disabled="true"/>

        <intercept-url pattern="/resources/**" access="permitAll" />
        <intercept-url pattern="/" access="permitAll" />
        <intercept-url pattern="/login" access="permitAll" />
        <intercept-url pattern="/api/**" access="permitAll" />

        <intercept-url pattern="/config/*" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />

        <intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />

        <access-denied-handler error-page="/403" />

        <form-login 
            login-page="/login" 
            default-target-url="/app/user/dashboard" 
            authentication-failure-url="/login?error=true" 
            username-parameter="userName"
            password-parameter="password" />

        <logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>

        <session-management invalid-session-url="/login?expired=true">
            <concurrency-control max-sessions="1" />
        </session-management>

    </http>


    <authentication-manager>
      <authentication-provider>
        <password-encoder ref="encoder" /> 
        <jdbc-user-service data-source-ref="dataSource"
          users-by-username-query=
            "select username, password, enabled from userdetails where userName=?"
          authorities-by-username-query=
            "select ud.username as username, rm.name as role from userdetails ud INNER JOIN rolemaster rm ON rm.id = ud.roleId  where username = ?" />
      </authentication-provider>
    </authentication-manager>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
    <beans:bean id="customLogoutSuccessHandler" class="com.pvn.mvctiles.configuration.CustomLogoutSuccessHandler" />

    <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
         <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
         <beans:property name="url" value="jdbc:mysql://localhost:3306/springmvc" />
         <beans:property name="username" value="root"/>
         <beans:property name="password" value="root"/>
         <beans:property name="initialSize" value="2" />
         <beans:property name="maxActive" value="5" />
    </beans:bean>       
</beans:beans>





在这里您需要覆盖loadUserByUsername方法
1.通过在方法中作为争论传递的用户名从数据库中加载用户密码.
2.从数据库中为用户加载权限,并构建GrantedAuthority
的列表 3.通过传递在步骤1和步骤2中获取的密码和授权来创建用户
4.返回UserDetail对象,以便spring容器本身负责认证和授权.

Here you need to override loadUserByUsername method
1. load user password from database by username passed as arguement in the method.
2. Load authorities for user from database and construct a list of GrantedAuthority
3. Create User by passing password and authorities fetched in step 1 and step 2
4. Return UserDetail object so that authentication and authorization will be taken care by spring container itself.

@Component
public class UserDaoImpl implements UserDao, UserDetailsService
{

    Logger          OUT = LoggerFactory.getLogger(UserDaoImpl.class);

    @Autowired
    SessionFactory  sessionFactory;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        try (Session session = sessionFactory.openSession();)
        {

            CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
            CriteriaQuery<DbUserDetails> userCriteria = criteriaBuilder.createQuery(DbUserDetails.class);
            Root<DbUserDetails> userRoot = userCriteria.from(DbUserDetails.class);
            userCriteria.select(userRoot).where(criteriaBuilder.equal(userRoot.get("userName"), username));

            Query<DbUserDetails> userQuery =session.createQuery(userCriteria);
            DbUserDetails dbUser = userQuery.getSingleResult();

            CriteriaQuery<RoleMaster> roleCriteria = criteriaBuilder.createQuery(RoleMaster.class);
            Root<RoleMaster> roleRoot = roleCriteria.from(RoleMaster.class);
            roleCriteria.select(roleRoot).where(criteriaBuilder.equal(roleRoot.get("id"), dbUser.getRoleId()));

            Query<RoleMaster> roleQuery =session.createQuery(roleCriteria);
            RoleMaster role = roleQuery.getSingleResult();

            List<GrantedAuthority> authList = new ArrayList<>();
            authList.add(new SimpleGrantedAuthority(role.getName()));

            return new User(username, dbUser.getPassword(),true, true, true, true, authList);
        }
        catch (Exception e)
        {
            OUT.error("Exception - {}", e);
            throw new UsernameNotFoundException("Exception caught", e);
        }
    }
}

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
{   
    @Autowired
    UserDaoImpl userDaoImpl;

    @Autowired
    public void configureUserDetailsService(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(userDaoImpl);
    }
    ...
}

这篇关于如何使用java和xml配置在Spring Security中配置jdbc身份验证管理器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆