SpringMVC+Shiro的基本使用及功能介绍
什么是Shiro
Shiro是一个强大且易于使用的Java安全框架,它提供了身份验证、授权、加密、会话管理等功能,可以帮助我们快速构建安全的Web应用程序。
SpringMVC集成Shiro
SpringMVC集成Shiro可以帮助我们快速构建安全的Web应用程序。以下是SpringMVC集成Shiro的基本步骤:
步骤1:添加Shiro依赖
在pom.xml文件中添加Shiro依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.1</version>
</dependency>
步骤2:配置ShiroFilter
在web.xml文件中配置ShiroFilter:
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
<init-param>
<param-name>configPath</param-name>
<param-value>classpath:shiro.ini</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在上面的示例中,我们定义了一个名为“shiroFilter”的过滤器,并将它映射到“/*”路径。我们还指定了一个名为“shiro.ini”的配置文件,它将在ShiroFilter初始化时加载。
步骤3:配置Shiro安全管理器
在shiro.ini文件中配置Shiro安全管理器:
[main]
# 定义Realm
myRealm = com.example.shiro.MyRealm
# 定义安全管理器
securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager
securityManager.realm = $myRealm
# 定义ShiroFilterFactoryBean
shiroFilterFactoryBean = org.apache.shiro.spring.web.ShiroFilterFactoryBean
shiroFilterFactoryBean.securityManager = $securityManager
shiroFilterFactoryBean.loginUrl = /login
shiroFilterFactoryBean.successUrl = /index
shiroFilterFactoryBean.unauthorizedUrl = /unauthorized
shiroFilterFactoryBean.filterChainDefinitions = /login = anon
/index = authc
/logout = logout
/unauthorized = anon
/** = authc
在上面的示例中,我们定义了一个名为“myRealm”的Realm,并将它配置到安全管理器中。我们还定义了一个名为“securityManager”的安全管理器,并将Realm配置到安全管理器中。我们还定义了一个名为“shiroFilterFactoryBean”的ShiroFilterFactoryBean,并将安全管理器配置到ShiroFilterFactoryBean中。我们还定义了登录URL、成功URL、未授权URL和过滤器链定义。
步骤4:编写Realm
在编写Realm时,我们需要继承org.apache.shiro.realm.AuthorizingRealm
类,并实现doGetAuthorizationInfo()
和doGetAuthenticationInfo()
方法。以下是一个简单的Realm示例:
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前用户信息
String username = (String) principals.getPrimaryPrincipal();
// 查询用户角色和权限信息
Set<String> roles = new HashSet<>();
Set<String> permissions = new HashSet<>();
// ...
// 创建AuthorizationInfo对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名查询用户信息
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户名或密码错误");
}
// 验证密码
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("用户名或密码错误");
}
// 创建AuthenticationInfo对象
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationInfo;
}
}
在上面的示例中,我们继承了AuthorizingRealm
类,并实现了doGetAuthorizationInfo()
和doGetAuthenticationInfo()
方法。在doGetAuthorizationInfo()
方法中,我们获取当前用户信息,并查询用户角色和权限信息。在doGetAuthenticationInfo()
方法中,我们获取用户名和密码,并根据用户名查询用户信息。如果用户不存在或密码不正确,将抛出异常。如果验证通过,我们将创建一个SimpleAuthenticationInfo
对象,并返回。
示例
以下是一个使用SpringMVC+Shiro实现用户登录和权限控制的示例:
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping("/login")
public String doLogin(String username, String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "redirect:/index";
} catch (AuthenticationException e) {
return "login";
}
}
@GetMapping("/index")
public String index() {
return "index";
}
@GetMapping("/admin")
public String admin() {
return "admin";
}
@GetMapping("/unauthorized")
public String unauthorized() {
return "unauthorized";
}
}
public class User {
private Integer id;
private String username;
private String password;
private String role;
// getter and setter
}
public class UserService {
private List<User> userList = new ArrayList<>();
public UserService() {
User user1 = new User();
user1.setId(1);
user1.setUsername("admin");
user1.setPassword("admin");
user1.setRole("admin");
userList.add(user1);
User user2 = new User();
user2.setId(2);
user2.setUsername("user");
user2.setPassword("user");
user2.setRole("user");
userList.add(user2);
}
public User getUserByUsername(String username) {
for (User user : userList) {
if (user.getUsername().equals(username)) {
return user;
}
}
return null;
}
}
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前用户信息
String username = (String) principals.getPrimaryPrincipal();
// 查询用户角色和权限信息
Set<String> roles = new HashSet<>();
Set<String> permissions = new HashSet<>();
User user = userService.getUserByUsername(username);
if (user != null) {
roles.add(user.getRole());
if ("admin".equals(user.getRole())) {
permissions.add("user:read");
permissions.add("user:write");
} else if ("user".equals(user.getRole())) {
permissions.add("user:read");
}
}
// 创建AuthorizationInfo对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 获取用户名和密码
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 根据用户名查询用户信息
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户名或密码错误");
}
// 验证密码
if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("用户名或密码错误");
}
// 创建AuthenticationInfo对象
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationInfo;
}
}
在上面的示例中,我们定义了一个名为“UserController”的控制器类,并使用@GetMapping
注解来映射GET请求,@PostMapping
注解来映射POST请求。我们还定义了一个名为“User”的JavaBean类,它包含了用户信息的属性和getter/setter方法。我们还定义了一个名为“UserService”的服务类,它用于查询用户信息。我们还定义了一个名为“MyRealm”的Realm,它用于身份验证和授权。我们还定义了一个名为“login.jsp”的登录页面,它包含了用户名和密码的输入框。我们还定义了一个名为“index.jsp”的首页,它包含了一个欢迎信息。我们还定义了一个名为“admin.jsp”的管理员页面,它包含了一个管理员信息。我们还定义了一个名为“unauthorized.jsp”的未授权页面,它包含了一个未授权信息。
总结
本文介绍了SpringMVC集成Shiro的基本步骤,并提供了一个使用SpringMVC+Shiro实现用户登录和权限控制的示例。通过本文的介绍,我们可以了解到如何在SpringMVC应用程序中使用Shiro实现安全控制。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringMVC+Shiro的基本使用及功能介绍 - Python技术站