我最近一直在研究 Spring Security,我需要知道如何使用数据库动态定义拦截 URL(在 Spring Security 中)。
我已经深入研究了整个互联网,但在这方面我找不到任何独特的(当然有用的)教程。
所以这就是我所做的:
首先我实现了 FilterInvocationSecurityMetadataSource 抽象类:
public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
public List<ConfigAttribute> getAttributes(Object object) {
FilterInvocation fi = (FilterInvocation) object;
String url = fi.getRequestUrl();
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
attributes = getAttributesByURL(url);
return attributes;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
public List<ConfigAttribute> getAttributesByURL(String inputUrl)
{
List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
Connection connection = null;
String url = "jdbc:mysql://173.0.0.22:3306/";
String dbName = "kheirkhahandb";
String driverName = "com.mysql.jdbc.Driver";
String userName = "kheirkhahan";
String password = "kheirkhahan";
try{
Class.forName(driverName).newInstance();
connection = DriverManager.getConnection(url+dbName, userName, password);
try{
Statement stmt = connection.createStatement();
String selectquery = "select * from URL_ACCESS where URL = '" + inputUrl +"'";
ResultSet rs = stmt.executeQuery(selectquery);
while(rs.next()){
MyConfigAttribute temp = new MyConfigAttribute();
String attr = rs.getString("ACCESS").toString();
temp.setAttr(attr);
attributes.add(temp);
}
}
catch(SQLException s){
System.out.println(s);
}
connection.close();
}
catch (Exception e){
e.printStackTrace();
}
return attributes;
}
我将我的security.xml设置为:
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/css/**" filters="none" />
<sec:filter-chain pattern="/images/**" filters="none" />
<sec:filter-chain pattern="/login.jsp*" filters="none" />
<sec:filter-chain pattern="/**"
filters="
securityContextPersistenceFilter,
logoutFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
<property name="accessDeniedHandler" ref="accessDeniedHandler" />
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp?error=entryPoint" />
</bean>
<bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/login.jsp?error=access_denied" />
</bean>
<bean id="authenticationProcessingFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="securityMetadataSource" ref="myFilterInvocationSecurityMetadataSource" />
</bean>
<bean id="myFilterInvocationSecurityMetadataSource" class="com.datx.dao.MyFilterSecurityMetadataSource">
</bean>
<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="/login.jsp?error=logout" />
<constructor-arg ref="logoutHandler">
</constructor-arg>
</bean>
<bean id="logoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"></bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider>
<sec:jdbc-user-service data-source-ref="dataSource"
group-authorities-by-username-query="
SELECT acg.ID, acg.GROUP_NAME, a.AUTHORITY_NAME AS AUTHORITY
FROM ACCESS_GROUPS acg, ACCESS_GROUP_MEMBERSHIP agm, GROUP_AUTHORITIES ga, AUTHORITIES a
WHERE agm.USERNAME = ? and acg.ID = ga.GROUP_ID and acg.ID = agm.GROUP_ID and ga.AUTHORITY_ID = a.ID
"
users-by-username-query="SELECT USERNAME,PASSWORD,IS_ACTIVE FROM USER where USERNAME = ?"
authorities-by-username-query="
SELECT ua.USERNAME, a.AUTHORITY_NAME AS AUTHORITY
FROM USER_AUTHORITIES ua, AUTHORITIES a
WHERE ua.USERNAME = ? and ua.AUTHORITY_ID = a.ID
" />
</sec:authentication-provider>
</sec:authentication-manager>
<bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<ref bean="roleVoter" />
</list>
</property>
</bean>
<bean id="roleVoter"
class="org.springframework.security.access.vote.RoleHierarchyVoter">
<property name="rolePrefix" value="" />
<constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy" class="com.datx.dao.MyRoleHierarchyImpl">
<property name="roleHierarchyEntryDaoJdbc" ref="RoleHierarchyEntryDaoJdbc" />
</bean>
</beans>
有一些我找不到的问题:
1. 我在 URL_ACCESS 数据库中插入了一些像 <"URL" , "ROLE"> 的对。但我不确定 getAttributes 方法是否工作正常
2. 我是否必须实现我在
3. 当用户使用错误的用户名/密码或尝试访问不允许的页面而不是被重定向到 login.jsp 时,我收到异常。这是为什么?
提前致谢