使用Grails 3.0

时间:2015-05-07 03:24:26

标签: mongodb grails spring-security spring-boot grails-3.0

如何使用新的普通Grails 3.0应用程序将用户存储在数据库中?

背景

  1. Shil和Spring Security插件尚不适用于Grails 3.0(听起来像Spring Boot是Grails安全的未来)。
  2. 有各种示例显示如何使用inMemoryAuthentication(),但它们似乎完全没有意义,因为密码最终以纯文本形式存储(此外,创建域模型只需要大约30秒的时间Grails的)。
  3. 几乎所有Grails应用程序都需要此功能。
  4. 我碰巧使用MongoDB,但这可能无关紧要。
  5. 相关:Grails 3 and Spring Security Plugin
  6. 我目前inMemoryAuthentication()正在使用以下内容:

    的build.gradle

    compile "org.springframework.boot:spring-boot-starter-security"
    


    的grails-app / CONF /弹簧/ resources.groovy

    import com.tincanworks.AppSecurityConfig
    beans = {
       webSecurityConfiguration(AppSecurityConfig)
       }
    


    AppSecurityConfig.groovy

    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.WebSecurityConfigurerAdapter
    
    class AppSecurityConfig extends WebSecurityConfigurerAdapter {
    
       @Override
       protected void configure(HttpSecurity http) throws Exception {
          http
             .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/assets/**").permitAll()
                .antMatchers("/admin/**").hasAnyRole("admin")
                .anyRequest().authenticated()
             .and()
                .formLogin().permitAll()
             .and()
                .logout().permitAll()
          }
    
       @Autowired
       public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth
             .inMemoryAuthentication()
                .withUser("user").password("123456").roles("user")
                .and()
                .withUser("admin").password("1qaz2wsx").roles("user", "admin")
          }
    
    }
    

    似乎答案可能与JdbcDaoImpl有关,但我不知道如何在Grails中解决这个问题。

2 个答案:

答案 0 :(得分:2)

<强> GORM基于

我写了两篇关于如何在Grails 3应用程序中使用spring-starter-security和GORM的博客文章(part 1 - In Memory Authpart 2 - Gorm-based Auth)。我还使用spring-starter-security创建了一个github repo with a working Grails 3应用程序。

基于JDBC - 未经测试

或者,如果您想使用标准的基于JDBC的身份验证,您可以使用以下SQL脚本创建数据库表

<强> HSQLDB

来自http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-schema.html

create table users(
      username varchar_ignorecase(50) not null primary key,
      password varchar_ignorecase(50) not null,
      enabled boolean not null);

  create table authorities (
      username varchar_ignorecase(50) not null,
      authority varchar_ignorecase(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      create unique index ix_auth_username on authorities (username,authority);

<强>的MySQL

这来自http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/

create table users (
    username varchar(50) not null primary key,
    password varchar(255) not null,
    enabled boolean not null) engine = InnoDb;

create table authorities (
    username varchar(50) not null,
    authority varchar(50) not null,
    foreign key (username) references users (username),
    unique index authorities_idx_1 (username, authority)) engine = InnoDb;

然后将configureGlobal方法更改为

@Autowired  //not sure if this is needed as you have the AppSecurityConfig bean referenced in resources.groovy
def datasource  //bean injected by Grails

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  auth
     .jdbcAuthentication()
     .dataSource(datasource)
}

答案 1 :(得分:0)

如果您想避免使用数据库从头开始构建整个用户管理层,可以考虑使用Stormpath

除其他外,它们提供使用Stormpath作为身份验证和授权提供程序的Spring Security Plugin。它们还有sample Spring Security app,显示插件的使用方式。由于您使用的是Java Annotations(而不是xml配置),请查看this branch

因此,总而言之,您需要定义的关键部分是:

  1. Stormpath Client Bean将通过Stormpath Java SDK与Stormpath进行快速安全的通信:

    //Let's create the Stormpath client using the apiKey.properties file from the User's home folder.
    @Bean
    ClientFactory stormpathClient(CacheManager cacheManager) {
        ClientFactory clientFactory = new ClientFactory();
        clientFactory.setApiKeyFileLocation(System.getProperty("user.home") + File.separator + ".stormpath" + File.separator + "apiKey.properties");
        clientFactory.setCacheManager(cacheManager);
        return clientFactory;
    }
    
  2. 您需要定义Stormpath身份验证提供程序,以便Spring Security可以透明地与Stormpath通信以对用户进行身份验证和授权:

    @Bean
    @Autowired
    public StormpathAuthenticationProvider stormpathAuthenticationProvider(Client client, String applicationRestUrl) throws Exception {
        StormpathAuthenticationProvider stormpathAuthenticationProvider = new StormpathAuthenticationProvider();
        stormpathAuthenticationProvider.setClient(client);
        stormpathAuthenticationProvider.setApplicationRestUrl(applicationRestUrl);
        return stormpathAuthenticationProvider;
    }
    
  3. applicationRestUrl需要指向存在所有用户/组的Stormpath应用程序:

    @Bean
    public String getApplicationRestUrl() {
        return "https://api.stormpath.com/v1/applications/9TqbyZ2po73eDP4gYo2H92";
    }
    
  4. 您的Spring Security配置需要配置为使用Stormpath身份验证提供程序:

    //Let's add the StormpathAuthenticationProvider to the `AuthenticationProvider`
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(stormpathAuthenticationProvider);
    }
    
  5. 最后,为了限制角色对资源的访问,您需要定义角色。例如:

    //The access control settings are defined here
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .formLogin()
                .and()
            .authorizeRequests()
                .accessDecisionManager(accessDecisionManager())
                .antMatchers("/account/*").hasAuthority("https://api.stormpath.com/v1/groups/36O9eBTN2oLtjoMSWLdnwL") //you are giving access to "/account/*" to users' that belong to the group univocally identified by this href value
                .and()
            .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/index.jsp")
                .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
    
  6. 免责声明,我是积极的Stormpath贡献者。

相关问题