下面是关于“spring boot整合Shiro实现单点登录的示例代码”的详细攻略。
环境准备
首先,我们需要准备以下环境:
- JDK 8
- Maven
- IDE:Eclipse 或者 Intellij IDEA
在环境准备完成后,我们接下来需要进行以下的准备工作。
创建Spring Boot工程
我们可以通过Maven快速构建一个Spring Boot应用程序,然后加上Shiro依赖即可。
- 打开Eclipse或者Intellij IDEA,创建一个普通的Maven工程;
- 在pom.xml文件中添加以下的Spring Boot依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
- 执行命令
mvn clean install
完成依赖的下载
Shiro基本配置
接下来,我们需要进行Shiro的基本配置
- 创建ShiroConfig类
在src/main/java下创建一个ShiroConfig类
@Configuration
public class ShiroConfig {
/**
* 配置Shiro到Spring容器
* @param securityManager
* @return
*/
@Bean(name = "shiroFilter")
protected ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//声明securityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//注册authcFilter过滤器
Map<String, Filter> filters = new LinkedHashMap<>();
filters.put("authc", authcFilter());
shiroFilterFactoryBean.setFilters(filters);
//为URL设置访问所需要的角色
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/login", "authc");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
shiroFilterFactoryBean.setLoginUrl("/login");
return shiroFilterFactoryBean;
}
/**
* 创建securityManager
*
* @return
*/
@Bean(name = "securityManager")
protected DefaultWebSecurityManager defaultWebSecurityManager(UserRealm bean) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//注入Realm
securityManager.setRealm(bean);
return securityManager;
}
/**
* 创建Realm
*
* @return
*/
@Bean(name = "realm")
public UserRealm userRealm() {
return new UserRealm();
}
/**
* 注册authcFilter过滤器
* @return
*/
@Bean(name = "authc")
public AuthenticationFilter authcFilter() {
UsernamePasswordAuthenticationFilter authcFilter = new UsernamePasswordAuthenticationFilter();
authcFilter.setLoginUrl("/login");
return authcFilter;
}
}
- 创建一个UserRealm类
在src/main/java下创建一个UserRealm类:
public class UserRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User user = (User) principalCollection.getPrimaryPrincipal();
//获取角色ResouceCode关联信息
List<ResouceCode> resouceCodeList = userService.selectResourceCodeList(user.getUserName());
//将role和url加入到授权对象中
if (resouceCodeList != null && resouceCodeList.size() > 0) {
for (ResouceCode resouceCode : resouceCodeList) {
authorizationInfo.addRole(resouceCode.getRoleCode().toUpperCase());
authorizationInfo.addStringPermission(resouceCode.getResCode().toLowerCase());
}
}
return authorizationInfo;
}
/**
* 验证 登录
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
String username = usernamePasswordToken.getUsername();
if (StringUtils.isBlank(username)) {
return null;
}
User user = userService.selectUserByUserName(username);
if (user == null) {
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getCredentialsSalt()), getName());
return authenticationInfo;
}
}
编写Controller和View
接下来,我们需要编写Controller和View
- 添加登录页面
在src/main/resources下创建login.html页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登陆</title>
</head>
<body>
<div>
<form method="post" th:action="@{/login}">
<div>
<label>用户名: <input type="text" name="username" required></label>
</div>
<div>
<label>密码: <input type="password" name="password" required></label>
</div>
<div><input type="submit" value="登陆"></div>
</form>
</div>
</body>
</html>
- 创建HomeController类
在src/main/java下创建一个HomeController类,实现登录成功后的跳转:
@Controller
public class HomeController {
/**
* 登录成功后跳转到主页面
*
* @return
*/
@RequestMapping("/home")
public String home() {
return "/views/home";
}
}
- 创建IndexController类
在src/main/java下创建一个IndexController类,实现登录和退出:
@Controller
public class IndexController {
/**
* 登录
*
* @return
*/
@RequestMapping("/login")
public String login() {
return "/views/login";
}
/**
* 退出
*
* @return
*/
@RequestMapping("/logout")
public String logout() {
SecurityUtils.getSubject().logout();
return "redirect:/login";
}
}
- 创建Home页面
在src/main/resources/views下创建一个home.html页面,实现登录验证后的统一页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>欢迎访问首页</h1>
</body>
</html>
两个示例说明
下面我们演示两个Shiro单点登录的应用:
示例一:普通登录
- 在浏览器中输入网址 http://localhost:8080/login,会跳转到登录页面;
- 在登录页面中输入用户名和密码,点击“登陆”,会跳转到应用的首页:http://localhost:8080/home,同时在请求头中设置了Cookie;
- 访问 http://localhost:8080/home,会发现并没有被拦截,说明登录成功;
示例二:多个应用的单点登录
假设有两个应用APP1和APP2,在浏览器中访问APP1,然后跳转到APP2,由于已经实现了Shiro单点登录,所以在访问APP2时,就无需再次输入用户名和密码。
- 访问APP1,执行登录操作,成功登录;
- 在APP1的页面上添加访问APP2页面的链接,并设置URL为APP2的登录页面URL;
- 点击APP2的链接,跳转到APP2的登录页面,此时我们并不需要再次输入用户名和密码;
- 点击APP2的首页链接,会发现并没有被拦截,说明登录成功。
总结
至此,我们已经完成了Spring Boot整合Shiro实现单点登录的示例代码。需要注意的是,这里的示例是最基本的示例,如果想要在实际应用中使用,还需要根据实际情况进行具体的配置和开发。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring boot整合Shiro实现单点登录的示例代码 - Python技术站