Apache Shiro 許可權控制 使用自定義的JdbcRealm(3)
阿新 • • 發佈:2018-11-30
使用自定義的realm 時需要配置shiro.ini 檔案 以及建一個類 MyJdbcRealm 繼承自 AuthorizingRealm 重寫其中的兩個方法
/** * 登入驗證 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // TODO Auto-generated method stub return null; }
/** * 為當前登入的使用者授予角色和許可權 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // TODO Auto-generated method stub return null; }
在shiro中配置
[main]
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized.jsp
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.taisen.realm.MyJdbcRealm
securityManager.realms=$myRealm
[urls]
/login=anon
/admin=authc
/student=roles[teacher]
/teacher=perms["teacher:query","teacher:add"]
下面是具體的實現方法:
需要連線資料庫 DBUtil
public class DBUtil {
private static final String username = "root";
private static final String password = "root";
private static final String className = "com.mysql.jdbc.Driver";
private static final String url = "jdbc:mysql://localhost:3306/db_shiro?useUnicode=true&characterEncoding=utf8&useSSL=false";
public static Connection conn = null;
public static PreparedStatement pstmt = null;
public static Connection getConnection() throws Exception{
Class.forName(className);
conn = DriverManager.getConnection(url, username, password);
return conn;
}
public static void close(Connection conn,PreparedStatement pstmt,ResultSet rs) throws SQLException{
conn.close();
pstmt.close();
if(rs != null){
rs.close();
}
}
public static void close(Connection conn,PreparedStatement pstmt) throws SQLException{
close(conn,pstmt,null);
}
public static void main(String[] args) {
try {
Connection conn = getConnection();
if(conn != null){
System.out.println("資料庫連線成功!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
操作資料庫UserDao:
public class UserDao {
private Connection connection;
public UserDao() throws Exception {
// TODO Auto-generated constructor stub
connection = DBUtil.getConnection();
}
public User getByUserName(String userName) throws Exception{
User resultUser = null;
String sql = "select * from t_user where userName = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs = pstmt.executeQuery();
if(rs.next()){
resultUser = new User();
resultUser.setId(rs.getInt("id"));
resultUser.setUserName(rs.getString("userName"));
resultUser.setPassword(rs.getString("password"));
}
DBUtil.close(connection, pstmt,rs);
return resultUser;
}
/*public static void main(String[] args) throws Exception {
UserDao userDao = new UserDao();
User user = userDao.getByUserName("java");
System.out.println(user);
}*/
/**
* 根據userName 獲取到roles
* @param userName
* @return
* @throws SQLException
*/
public Set<String> getRoles(String userName) throws SQLException {
Set roles = new HashSet();
String sql = "select * from t_role r LEFT JOIN t_user u on r.id = u.role_id where u.userName = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs = pstmt.executeQuery();
if(rs.next()){
roles.add(rs.getString("roleName"));
}
return roles;
}
/**
* 根據傳入的userName 返回得到的perms
* @param object
* @return
* @throws SQLException
*/
public Set<String> getPerms(String userName) throws SQLException {
Set permissions = new HashSet();
String sql = "select * from t_user u,t_role r,t_permission p where u.role_id = r.id and p.role_id = r.id and u.userName = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userName);
ResultSet rs = pstmt.executeQuery();
if(rs.next()){
permissions.add(rs.getString("permissionName"));
}
DBUtil.close(connection, pstmt, rs);
return permissions;
}
}
重點 MyJdbcRealm。 在點選登入按鈕後後到Controller中的login方法 呼叫subject.login(token)方法時會呼叫下面的自定義
Realm
public class MyJdbcRealm extends AuthorizingRealm{
/**
* 登入驗證
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
AuthenticationInfo auth = null;
try {
UserDao userdao = new UserDao();
String username = (String) token.getPrincipal(); //獲取到userName
User user = userdao.getByUserName(username);
if(user != null){
auth = new SimpleAuthenticationInfo(username, user.getPassword(),"XX");
return auth;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return auth;
}
return auth;
}
/**
* 為當前登入的使用者授予角色和許可權
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
String userName = (String)principals.getPrimaryPrincipal();
UserDao userdao;
SimpleAuthorizationInfo auth = null;
try {
userdao = new UserDao();
auth = new SimpleAuthorizationInfo();
auth.setRoles(userdao.getRoles(userName));
auth.setStringPermissions(userdao.getPerms(userName));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return auth;
}
}
每次發起請求時都會驗證許可權。