Dealing with OpenId(5)Spring Security and OpenId Work together

Dealing with OpenId(5)Spring Security and OpenId Work together

1. The Spring Security Version
<properties>
<spring.version>3.1.1.RELEASE</spring.version>
<spring-security.version>3.1.0.M2</spring-security.version>
</properties>
...snip...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.openid4java</groupId>
<artifactId>openid4java-nodeps</artifactId>
<version>0.9.6</version>
</dependency>

2. My spring security configuration file security-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:authentication-manager>
<security:authentication-provider ref="openidAuthenticationProvider" />
<security:authentication-provider ref="authenticationProvider" />
</security:authentication-manager>
<bean id="openidAuthenticationProvider" class="org.springframework.security.openid.OpenIDAuthenticationProvider">
<property name="userDetailsService" ref="registeringUserService" />
</bean>
<bean id="authenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="registeringUserService" />
</bean>
<security:http pattern="/openidlogin.jsp*" security="none"/>
<security:http pattern="/images/*" security="none" />
<security:http pattern="/css/*" security="none" />
<security:http pattern="/js/*" security="none" />
<security:debug />
<security:http access-denied-page="/denied.jsp" use-expressions="true">
<security:form-login login-processing-url="/j_spring_security_check" login-page="/openidlogin.jsp" authentication-failure-url="/openidlogin.jsp?login_error=true"/>
<security:intercept-url pattern="/index.jsp" access="permitAll" />
<security:intercept-url pattern="/user/**" access="hasRole('ROLE_USER')" />
<security:intercept-url pattern="/super/**" access="hasRole('ROLE_SUPERVISOR')" />
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/**" access="denyAll" />
<security:logout
invalidate-session="true"
logout-success-url="/openidlogin.jsp"
logout-url="/j_spring_security_logout"/>
<security:openid-login
user-service-ref="registeringUserService"
authentication-failure-url="/openidlogin.jsp?login_error=true"
default-target-url="/index.jsp">
<security:attribute-exchange identifier-match="https://www.google.com/.*">
<security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true" />
<security:openid-attribute name="firstName" type="http://axschema.org/namePerson/first" required="true" />
<security:openid-attribute name="lastName" type="http://axschema.org/namePerson/last" required="true" />
</security:attribute-exchange>
<security:attribute-exchange identifier-match=".*yahoo.com.*">
<security:openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
<security:openid-attribute name="fullname" type="http://axschema.org/namePerson" required="true" />
</security:attribute-exchange>
<security:attribute-exchange identifier-match=".*myopenid.com.*">
<security:openid-attribute name="email" type="http://schema.openid.net/contact/email" required="true"/>
<security:openid-attribute name="fullname" type="http://schema.openid.net/namePerson" required="true" />
</security:attribute-exchange>
</security:openid-login>
</security:http>

<bean id="registeringUserService" class="com.sillycat.easyopenidgoogle.service.OpenIdUserDetailsService" />

3. My java source code for load the userdetail by username and email from openid
I just add some mock codes here, if I want, I can get to a database or XML file to do that.
package com.sillycat.easyopenidgoogle.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.openid.OpenIDAttribute;
import org.springframework.security.openid.OpenIDAuthenticationToken;

import com.sillycat.easyopenidgoogle.model.GoogleUser;
import com.sillycat.easyopenidgoogle.model.UserAuthority;
import com.sillycat.easyopenidgoogle.model.UserRole;

public class OpenIdUserDetailsService implements UserDetailsService,
AuthenticationUserDetailsService<OpenIDAuthenticationToken> {

private final Map<String, GoogleUser> registeredUsers = new HashMap<String, GoogleUser>();

public UserDetails loadUserDetails(OpenIDAuthenticationToken openIDToken)
throws UsernameNotFoundException {
String id = openIDToken.getIdentityUrl();
System.out.println("identy = " + id);
String email = null;
String firstName = null;
String lastName = null;
String fullName = null;
List<OpenIDAttribute> attributes = openIDToken.getAttributes();
for (OpenIDAttribute attribute : attributes) {
if (attribute.getName().equals("email")) {
email = attribute.getValues().get(0);
System.out.println("email = " + email);
}
if (attribute.getName().equals("firstName")) {
firstName = attribute.getValues().get(0);
System.out.println("firstName = " + firstName);
}
if (attribute.getName().equals("lastName")) {
lastName = attribute.getValues().get(0);
System.out.println("lastName = " + lastName);
}
if (attribute.getName().equals("fullname")) {
fullName = attribute.getValues().get(0);
System.out.println("fullName = " + fullName);
}
}
GoogleUser user = new GoogleUser();
user.setUsername(email);

UserRole userRole = new UserRole();
UserAuthority userAuthority = new UserAuthority();
userAuthority.setAuthorityAlias("Access the main page!");
userAuthority.setAuthorityName("ROLE_USER");
userRole.getRoleAuthorities().add(userAuthority);
user.getUserRoles().add(userRole);
registeredUsers.put(id, user);
return user;
}

public UserDetails loadUserByUsername(String id)
throws UsernameNotFoundException {
GoogleUser user = registeredUsers.get(id);
if (id == null) {
throw new UsernameNotFoundException(id);
}
if (user == null) {
user = new GoogleUser();
user.setUsername(id);
user.setPassword("111111");

UserRole userRole = new UserRole();
UserAuthority userAuthority = new UserAuthority();
userAuthority.setAuthorityAlias("Access the main page!");
userAuthority.setAuthorityName("ROLE_USER");
userRole.getRoleAuthorities().add(userAuthority);
user.getUserRoles().add(userRole);
}
return user;
}
}

That is it. I only need 2 forms to login:
<form name="f1" action="j_spring_openid_security_check" method="POST">
<table>
<tr>
<td>OpenID Identity:</td>
<td><input type='text' name='openid_identifier' value='https://www.google.com/accounts/o8/id'/></td></tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
</form>

<form name="f2" action="j_spring_security_check" method="POST">
<table>
<tr>
<td>User Name:</td>
<td><input id="j_username" type='text' name='j_username' style="width:150px" /></td>
</tr>
<tr>
<td>Password: </td>
<td><input id="j_password" type='password' name='j_password' style="width:150px" /></td>
</tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
</form>

references:
http://http.git.springsource.org/greenhouse/greenhouse.git
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity-single.html#ns-openid
http://forum.springsource.org/showthread.php?113699-How-to-have-both-an-openid-login-and-a-form-login-side-by-side
### URL Security Constraints and Best Practices When addressing security constraints related to URLs, it's essential to consider several aspects, including how URLs are structured, how they interact with web applications, and the potential vulnerabilities they might expose. Below is a detailed overview of key constraints and best practices: #### URL Structure and Redirection One of the best practices for URL management is to ensure that your web framework gracefully handles trailing slashes. Most web frameworks provide an option to redirect users to either the trailed or untrailed version of a URL. Activating this feature helps maintain a consistent URL structure, which can prevent duplicate content issues and improve SEO. Additionally, using query strings for filtering and pagination is a recommended practice, as it allows for dynamic content delivery without altering the main URL structure [^1]. #### Security Concerns URLs can also introduce security concerns, particularly when dealing with cookies and session management. One significant issue is ambient authority, where cookies can be misused for authentication purposes. This problem arises because the naming resource and the authentication process can be decoupled, leading to potential security breaches. Another critical concern is session stealing, where an attacker can hijack a user's session by obtaining their session cookie. To mitigate these risks, it's crucial to implement encryption and integrity protection mechanisms, such as HTTPS, to secure the communication between the client and server [^2]. #### Input Validation and Sanitization Another important aspect of URL security is input validation and sanitization. When constructing URLs, especially those that include user-provided data, it's vital to validate and sanitize any inputs to prevent injection attacks, such as SQL injection or cross-site scripting (XSS). Proper validation ensures that only expected and safe data is processed, reducing the risk of malicious activity. #### Secure Query Parameters When using query strings for filtering and pagination, it's essential to handle the parameters securely. Highly separated fields, which are fields with a high degree of uniqueness, can be optimized for query performance by indexing them independently. However, it's important to balance this optimization with the potential impact on table writing efficiency, as too many indexes can slow down write operations. For large tables, following best practices for indexing, such as those provided by iDB Cloud, can help maintain optimal performance while ensuring security [^4]. #### Historical Context and SQL Development Understanding the historical context of SQL development can also provide insights into modern security practices. Oracle, the first commercially available SQL DBMS, played a significant role in shaping the SQL landscape. Early implementations of SQL were far from Codd's original ideas, and key features like referential integrity and nested queries in the `FROM` clause took many years to become standard. This evolution highlights the importance of staying updated with the latest security standards and best practices, as the technology and threats continue to evolve [^5]. ### Code Example: Secure URL Handling in a Web Application Here is an example of how to handle URL redirection and query string parameters securely in a web application using Python and Flask: ```python from flask import Flask, redirect, url_for, request, escape app = Flask(__name__) @app.route('/redirect') def handle_redirect(): # Safely redirect to a URL with a trailing slash if not request.path.endswith('/'): return redirect(url_for(request.endpoint, **request.view_args), code=301) return "Redirected successfully" @app.route('/search') def search(): # Securely handle query parameters query = escape(request.args.get('q', '')) page = int(escape(request.args.get('page', '1'))) # Perform search logic here return f"Searching for '{query}' on page {page}" if __name__ == '__main__': app.run(ssl_context='adhoc') # Enable HTTPS for secure communication ``` In this example, the `handle_redirect` function ensures that URLs are consistently formatted with a trailing slash, while the `search` function securely processes query parameters using the `escape` function to prevent XSS attacks. The application also runs with an ad-hoc SSL context to enable HTTPS, which is crucial for securing the communication between the client and server. ### Summary By following best practices such as ensuring consistent URL structures, validating and sanitizing inputs, handling query parameters securely, and implementing encryption and integrity protection, developers can significantly enhance the security of their web applications. Staying informed about the historical context and evolving standards in web development can also help in making informed decisions about security practices.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值