关于Spring Boot在Web应用中基于JdbcRealm安全验证的完整攻略,可以分为以下几个部分:
- 依赖配置
在项目的pom.xml文件中添加Shiro和JDBC驱动的依赖:
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
- Shiro配置
Shiro通过Ini配置文件或者编程方式来进行配置,这里我们选择编程方式。实现ShiroConfig类,在里面配置需要的对象,例如Realm、SecurityManager等。具体代码如下:
@Configuration
public class ShiroConfig {
/**
* 自定义Realm实现
*/
@Bean
public JdbcRealm jdbcRealm() {
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource()); // 设置数据源
jdbcRealm.setAuthenticationQuery("SELECT password FROM users WHERE username = ?"); // 查询用户密码
jdbcRealm.setUserRolesQuery("SELECT r.role_name FROM user_role ur, roles r WHERE ur.user_id = (SELECT id FROM users WHERE username = ?) AND ur.role_id = r.id"); // 查询用户角色
jdbcRealm.setPermissionsQuery("SELECT p.permission_name FROM roles_permissions rp, permissions p WHERE rp.permission_id = p.id AND rp.role_id = (SELECT id FROM roles WHERE role_name = ?)"); // 查询角色权限
jdbcRealm.setCredentialsMatcher(hashedCredentialsMatcher()); // 设置密码校验器
return jdbcRealm;
}
/**
* 配置SecurityManager
*/
@Bean
public SecurityManager securityManager() {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(jdbcRealm());
return securityManager;
}
/**
* 密码校验器
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("MD5"); // MD5加密
matcher.setHashIterations(1); // 迭代次数
return matcher;
}
/**
* 数据源配置
*/
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
/**
* 配置Shiro过滤器
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
shiroFilterFactoryBean.setLoginUrl("/login"); // 设置登录页面
shiroFilterFactoryBean.setSuccessUrl("/index"); // 设置登录成功跳转页面
shiroFilterFactoryBean.setUnauthorizedUrl("/403"); // 设置未授权页面
// 配置过滤器链
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/static/**", "anon"); // 静态资源不拦截
filterChainDefinitionMap.put("/logout", "logout"); // 登出
filterChainDefinitionMap.put("/login", "anon"); // 登录页面不拦截
filterChainDefinitionMap.put("/**", "authc"); // 其他页面需要认证
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
- 编写登录页面
在登录页面,需要提交用户名和密码,具体代码如下:
<form method="post" action="/login">
<label>用户名:</label>
<input type="text" name="username"/>
<br/>
<label>密码:</label>
<input type="password" name="password"/>
<br/>
<input type="submit" value="登录"/>
</form>
- 编写控制器
在控制器中,需要实现登录、登出等操作,具体代码如下:
@Controller
public class UserController {
/**
* 跳转到登录页面
*/
@GetMapping("/login")
public String login() {
return "login";
}
/**
* 登录
*/
@PostMapping("/login")
public String doLogin(String username, String password) {
// 创建UsernamePasswordToken
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// 获取Subject对象
Subject subject = SecurityUtils.getSubject();
try {
// 进行登录
subject.login(token);
return "redirect:/index";
} catch (AuthenticationException e) {
// 登录失败
return "login";
}
}
/**
* 登出
*/
@GetMapping("/logout")
public String logout() {
// 获取Subject对象
Subject subject = SecurityUtils.getSubject();
// 登出
subject.logout();
return "redirect:/login";
}
/**
* 首页
*/
@GetMapping("/index")
public String index() {
return "index";
}
/**
* 未授权页面
*/
@GetMapping("/403")
public String unauthorized() {
return "403";
}
}
- 配置示例
我们可以通过在数据库中添加用户表、角色表、权限表,来实现基于JdbcRealm的安全验证。例如在用户表中添加了一条记录:
INSERT INTO users(id, username, password) VALUES(1, 'test', '098f6bcd4621d373cade4e832627b4f6');
其中密码使用了MD5对123456
进行了加密。
我们还可以在角色表中添加一个admin
角色,在用户角色表中为test
用户添加了admin
角色。在权限表中为admin
角色添加了一个/test
的权限。
这样,在访问/test
页面时,需要用户进行登录,才能够访问。如果用户没有admin
角色的权限,将会跳转到未授权页面。
通过以上步骤,我们就可以实现基于JdbcRealm的安全验证过程。
示例代码请参考:https://github.com/gaohan0719/shiro-jdbc-demo
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot在Web应用中基于JdbcRealm安全验证过程 - Python技术站