上一篇,我们讲述的spring security的基础使用。但是对于一些复杂权限场景,我们需要更高级一些的功能。
我们接着往下展示它的高级部分。
<security:authentication-manager>的内部高级设置
在上一篇的Spring security设置示例中,我设置了authentication-manager来检查登录用户凭证,并使用标签中定义的纯文本用户。如下所示,您可以在此处为您的应用程序定义多个用户。
security:user-service
<security:user name=“stiti” password=“mindfire” authorities=“USER” />
<security:user name=“ram” password=“pass1234” authorities=“ADMIN” />
.
.
and so on…
</security:user-service>
上面的方式,是简单的校验。对于更复杂的,比如要对数据库中的Users表进行身份验证,则可以使用<security:jdbc-user-service>替换<security:user-service> … </ security:user-service>标记。如下。
security:authentication-manager
security:authentication-provider
<security:jdbc-user-service
data-source-ref=“dataSource”
users-by-username-query=
“SELECT username, password FROM users WHERE username=? AND active=1”
authorities-by-username-query=
“SELECT US.username, UR.authority
FROM users US, user_roles UR
WHERE US.user_id = UR.user_id and US.username =?”
/>
</security:authentication-provider>
</security:authentication-manager>
在这里,您执行SQL查询以从数据库中的“users”表中获取用户名和密码。
类似地,用户名的授权权限也从“user_roles”数据库表中获取。
在这里您可以注意到我在“data-source-ref”属性中提到了数据源引用。这是“dataSource”。
因此,您需要在应用程序Context xml文件中定义一个id =“dataSource”的Bean。如下。
<beans …>
…
…
…
我在上面的数据库属性标记的“value”中提供了占位符。您可以用实际值替换它们。
如果要通过数据访问对象层(DAO)@Service对数据库中的Users表进行身份验证,则可以按如下方式进行配置。
security:authentication-manager
<security:authentication-provider user-service-ref=“loginService”>
</security:authentication-provider>
</security:authentication-manager>
在这里,您执行SQL查询以从数据库中的“users”表中获取用户名和密码。
类似地,用户名的授权权限也从“user_roles”数据库表中获取。
在这里您可以注意到我在<security:authentication-provider>标记中提到了user-service-ref =“loginService”。
spring安全性将使用名为“loginService”的存储库服务获取身份验证。
我们可以为我们的登录服务创建数据访问对象接口和实现。
比如:我们创建一个名为“LoginDAO.java”的接口java类
package com.stiti.dao;
import com.stiti.model.AppUser;
public interface LoginDAO {
Object findUserByUsername(String username);
}
com.stiti.model.AppUser和 AppUserRole是Model类。
您可以使用自己的方式获取数据库用户和用户角色表并定义 *findUserByUsername(String username)*函数体。
*findUserByUsername(String username)*返回AppUser类型对象。
package com.stiti.dao.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.HibernateException;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.stiti.dao.LoginDAO;
import com.stiti.model.AppUser;
import com.stiti.model.AppUserRole;
/**
- @author Stiti Samantray
*/
@Repository(“loginDao”)
@Transactional
public class LoginDAOImpl implements LoginDAO {
@Autowired
SessionFactory sessionFactory;
/**
- Finds the AppUser which has a matching username
- @param username
- @return
*/
@Override
public AppUser findUserByUsername( String username )
{
Session session = sessionFactory.getCurrentSession();
List users = new ArrayList();
List userData = new ArrayList();
Set userRoles = new HashSet(0);
try {
String hql = “FROM AppUser U WHERE U.username = :username”;
org.hibernate.Query query = session.createQuery(hql)
.setParameter(“username”, username);
users = query.list();
} catch (HibernateException e) {
System.err.println("ERROR: "+ e.getMessage());
}
AppUser user = null;
if(users.size() > 0) {
user = (AppUser) users.get(0);
// Get the user roles
try {
String hql = “FROM AppUserRole R WHERE R.username = :username”;
org.hibernate.Query query = session.createQuery(hql)
.setParameter(“username”, username);
userRoles = new HashSet(query.list());
} catch (HibernateException e) {
// You can log the error here. Or print to console
}
user.setUserRole(userRoles);
}
return user;
}
}
findUserByUsername(String username) 返回AppUser类型对象。
package com.stiti.service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.stiti.model.AppUser;
import com.stiti.model.AppUserRole;
import com.stiti.dao.LoginDAO;
/**
- This class gets the appuser information from the database and
- populates the “org.springframework.security.core.userdetails.User” type object for appuser.
- @author Stiti Samantray
*/
@Service(“loginService”)
public class LoginServiceImpl implements UserDetailsService {
@Autowired
private LoginDAO loginDao;
/**
- @see UserDetailsService#loadUserByUsername(String)
*/
@Override
public UserDetails loadUserByUsername( String username ) throws UsernameNotFoundException
{
AppUser user = (AppUser) loginDao.findUserByUsername(username);
List authorities = buildUserAuthority(user.getUserRole());
return buildUserForAuthentication(user, authorities);
}
private List buildUserAuthority(Set appUserRole) {
Set setAuths = new HashSet();
// Build user’s authorities
for (AppUserRole userRole : appUserRole) {
System.out.println(“****” + userRole.getUserRole());
setAuths.add(new SimpleGrantedAuthority(userRole.getUserRole()));
}
List Result = new ArrayList(setAuths);
return Result;
}
private User buildUserForAuthentication(AppUser user, List authorities) {
return new User(user.getUsername(), user.getPassword(), true, true, true, true, authorities);
}
最后
面试题文档来啦,内容很多,485页!
由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。
1111道Java工程师必问面试题
MyBatis 27题 + ZooKeeper 25题 + Dubbo 30题:
Elasticsearch 24 题 +Memcached + Redis 40题:
Spring 26 题+ 微服务 27题+ Linux 45题:
Java面试题合集:
中…(img-wyCtZx3Z-1714334147564)]
Elasticsearch 24 题 +Memcached + Redis 40题:
[外链图片转存中…(img-1aKQms1N-1714334147565)]
Spring 26 题+ 微服务 27题+ Linux 45题:
[外链图片转存中…(img-1CyMRmjz-1714334147565)]
Java面试题合集:
[外链图片转存中…(img-sX3qxcjR-1714334147565)]