Spring Security - wie kann ich definieren, intercept-url dynamisch mit der Datenbank?
Arbeite ich schon an einer Feder, die Sicherheit vor kurzem, und ich muss wissen wie ich definieren kann, intercept-url (in Spring Security) dynamisch über eine Datenbank.
Habe ich schon gegraben, tief das ganze internet und ich konnte keine eindeutige (und natürlich sinnvoll) tutorial in diesem Bereich.
So, hier ist was ich getan habe:
Zuerst habe ich umgesetzt FilterInvocationSecurityMetadatasource Abstrakte Klasse:
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;
}
und ich meine security.xml wie:
<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>
Es gibt einige Probleme, die ich nicht herausfinden:
1. Habe ich eingefügt, einige Paare wie <,"URL" , "ROLLE"> in URL_ACCESS Datenbank. Aber ich bin mir nicht sicher, ob getAttributes-Methode ist in Ordnung, oder nicht
2. Muss ich, um alle jene Filter, die ich verwendet
3. Ich erhalte Ausnahme, wenn ein Benutzer einen falschen Benutzernamen/Passwort oder versucht, auf nicht-erlaubte-Seiten, anstelle der Weiterleitung auf login.jsp. Warum ist das so?
Vielen Dank im Voraus
- Ich bin mir nicht sicher, warum Sie wollen, dies zu tun. Ist Ihre Bewerbung so dynamisch, dass neue url erstellt werden, wenn mit der Anwendung, müssen Sie abgefangen werden. Ich in der Regel nie alles in eine Datenbank, die nur änderungen mit einer neuen Entwicklung daher eine neue Version.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als erstes würde ich sicherstellen, dass Sie konsultiert haben die FAQ über diese, um sicherzustellen, Sie wirklich wollen, dies zu tun. Als tom angedeutet, ist es im Allgemeinen nicht ratsam, diese Informationen in einer Datenbank.
In Bezug auf ob/warum Sie Ihre aktuelle code arbeiten, ist es schwierig zu sagen ohne weitere details. Zum Beispiel, was sind die Fehler, die Sie sehen in den logs? Die Frage in #2 scheint nicht vollständig zu sein. Was machen die Spring Security logs sagen?
Wenn Sie gehen, um stick mit diesem plan, ich würde weiterhin voll verwenden Sie die namespace-Konfiguration und nutzen Sie eine BeanPostProcessor (wie bereits auf der FAQ) zu tauschen die
FilterInvocationServiceSecurityMetadataSource
. Eine Implementierung könnte wie folgt Aussehen:Dann Ihre benutzerdefinierten
FilterInvocationServiceSecurityMetadataSource
angegeben werden kann, in der Spring-Konfiguration zusammen mit derFilterInvocationServiceSecurityMetadataSourceBeanPostProcessor
.Danke Euch beiden Tom und Rob für Eure schnellen Antworten.
Zuerst von alle, bin ich Total bewusst "speichern von url-mustern in der Datenbank ist keine gute Idee". Wir sind jedoch bemüht, um alles zu verwalten dynamisch. Es gibt also keine andere Wahl.
Wie sich herausstellte, gab es einige kleinere Probleme mit meinem code.
Hier beantworte ich jede meiner Fragen eine nach der anderen.
Meine getAttributes-Methode funktioniert ganz gut. Aber es gibt eine alternative zum laden von url-mustern.
Ich konnte laden alle url-Muster und Ihre entsprechenden Rollen zunächst in eine HashedMap getrennt. Und in getAttributes-Methode, ich könnte einfach nachschlagen, die HasehdMap statt.
In Kürze wird es so sein würde:
Und in meinem getAttributes-Methode ich verwenden Sie diese url-Zugriff Sache.
Die Frage ist irgendwie getrimmt!
Ich war versucht zu Fragen, über diese Filter in springSecurityFilterChain bean.
Wurde ich empfangen Ausnahmen, weil in authenticationProcessingFilter bean gab es keine solchen Eigenschaften.
Damit ich wieder schreiben Sie so:
und natürlich musste ich mir vorstellen authenticationFailureHandler bean dies auch:
Nun bin ich auch nicht erhalten, keine Ausnahmen.
Aber hier stellt sich eine weitere Frage:
Ich kann nicht verstehen, ob Benutzername/Passwort ist falsch oder der Benutzername nicht haben Zugriff auf die angeforderte Seite.
In beiden Fällen, wird der Benutzer umgeleitet wird nach diesen bean:
Warum ist es die Kontrolle beide Fälle?
access denied
undentry point
. Für Die ehemaligen werfe ich403
Ausnahme, und für letztere wird der Benutzer auf die Seite umgeleitet. Alle die ich tun musste, war mit anderenaccess denied exception handler
und Griff403
Antwort von unserer Benutzeroberfläche.