使用 Grails 3.0 在数据库中存储 Spring 引导用户
Storing Spring Boot users in a database with Grails 3.0
如何使用新的普通 Grails 3.0 应用程序将用户存储在数据库中?
背景:
- Shiro 和 Spring 安全插件对于 Grails 3.0 尚不可用(听起来 Spring Boot 是 Grails 安全的未来)。
- 有各种示例显示如何使用
inMemoryAuthentication()
,但它们似乎完全没有意义,因为密码最终以纯文本形式存储(此外,创建域只需要大约 30 秒的时间) Grails 中的模型)。
- 几乎所有 Grails 应用程序都需要此功能。
- 我碰巧在使用 MongoDB,但这可能无关紧要。
- 相关:
我目前 inMemoryAuthentication()
正在处理以下内容:
build.gradle
compile "org.springframework.boot:spring-boot-starter-security"
grails-app/conf/spring/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。
如果您想避免使用数据库从头开始构建整个用户管理层,您可以考虑 Stormpath。
除其他外,他们还提供 Spring Security Plugin that uses Stormpath as the authentication and authorization provider. They also have a sample Spring Security app that shows how the plugin is used. Since you are using Java Annotations (rather than xml configuration) take a look at this branch。
因此,总而言之,您需要定义的关键部分是:
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;
}
您将需要定义 Stormpath 身份验证提供程序,以便 Spring 安全性可以透明地与 Stormpath 通信以对用户进行身份验证和授权:
@Bean
@Autowired
public StormpathAuthenticationProvider stormpathAuthenticationProvider(Client client, String applicationRestUrl) throws Exception {
StormpathAuthenticationProvider stormpathAuthenticationProvider = new StormpathAuthenticationProvider();
stormpathAuthenticationProvider.setClient(client);
stormpathAuthenticationProvider.setApplicationRestUrl(applicationRestUrl);
return stormpathAuthenticationProvider;
}
applicationRestUrl
需要指向将存在所有 users/groups 的 Stormpath 应用程序:
@Bean
public String getApplicationRestUrl() {
return "https://api.stormpath.com/v1/applications/9TqbyZ2po73eDP4gYo2H92";
}
您的 Spring 安全配置需要配置为使用 Stormpath 身份验证提供程序:
//Let's add the StormpathAuthenticationProvider to the `AuthenticationProvider`
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(stormpathAuthenticationProvider);
}
最后,为了按角色限制对资源的访问,您需要定义角色。例如:
//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();
}
免责声明,我是活跃的 Stormpath 贡献者。
基于 GORM
我写了两篇博文(part 1 - In Memory Auth and part 2 - Gorm-based Auth) on how to use spring-starter-security and GORM in a Grails 3 application. I also created a github repo with a working Grails 3 应用程序使用 spring-starter-security。
基于 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)
}
如何使用新的普通 Grails 3.0 应用程序将用户存储在数据库中?
背景:
- Shiro 和 Spring 安全插件对于 Grails 3.0 尚不可用(听起来 Spring Boot 是 Grails 安全的未来)。
- 有各种示例显示如何使用
inMemoryAuthentication()
,但它们似乎完全没有意义,因为密码最终以纯文本形式存储(此外,创建域只需要大约 30 秒的时间) Grails 中的模型)。 - 几乎所有 Grails 应用程序都需要此功能。
- 我碰巧在使用 MongoDB,但这可能无关紧要。
- 相关:
我目前 inMemoryAuthentication()
正在处理以下内容:
build.gradle
compile "org.springframework.boot:spring-boot-starter-security"
grails-app/conf/spring/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。
如果您想避免使用数据库从头开始构建整个用户管理层,您可以考虑 Stormpath。
除其他外,他们还提供 Spring Security Plugin that uses Stormpath as the authentication and authorization provider. They also have a sample Spring Security app that shows how the plugin is used. Since you are using Java Annotations (rather than xml configuration) take a look at this branch。
因此,总而言之,您需要定义的关键部分是:
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; }
您将需要定义 Stormpath 身份验证提供程序,以便 Spring 安全性可以透明地与 Stormpath 通信以对用户进行身份验证和授权:
@Bean @Autowired public StormpathAuthenticationProvider stormpathAuthenticationProvider(Client client, String applicationRestUrl) throws Exception { StormpathAuthenticationProvider stormpathAuthenticationProvider = new StormpathAuthenticationProvider(); stormpathAuthenticationProvider.setClient(client); stormpathAuthenticationProvider.setApplicationRestUrl(applicationRestUrl); return stormpathAuthenticationProvider; }
applicationRestUrl
需要指向将存在所有 users/groups 的 Stormpath 应用程序:@Bean public String getApplicationRestUrl() { return "https://api.stormpath.com/v1/applications/9TqbyZ2po73eDP4gYo2H92"; }
您的 Spring 安全配置需要配置为使用 Stormpath 身份验证提供程序:
//Let's add the StormpathAuthenticationProvider to the `AuthenticationProvider` @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(stormpathAuthenticationProvider); }
最后,为了按角色限制对资源的访问,您需要定义角色。例如:
//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(); }
免责声明,我是活跃的 Stormpath 贡献者。
基于 GORM
我写了两篇博文(part 1 - In Memory Auth and part 2 - Gorm-based Auth) on how to use spring-starter-security and GORM in a Grails 3 application. I also created a github repo with a working Grails 3 应用程序使用 spring-starter-security。
基于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)
}