principle
The returned user information is configured in deployerConfigContext.xml
Since you want to customize the returned user information, just inherit org.jasig.services.persondir.support.stubbersonattributedao
1. Create com.jadyer.sso.authentication extensions stubbersonattributedao and copy getPerson() method
Use @ Component(value = "attributeRepository") to define its BeanID
2. Comment < bean in deployerConfigContext.xml Id = "attributerepository" > and < util: Map Id = "attrrepobackingmap" > configuration
3. Modify \ WEB-INF\view\jsp\protocol .0\casServiceValidationSuccess.jsp (do not change the one below 3.0)
For specific changes, see the code posted below
In addition, the information returned to the client is defined by the org.jasig.services.persondir.IPersonAttributeDao interface
Stubbersonattributedao is one of the implementations of IPersonAttributeDao
Other implementations, such as SingleRowJdbcPersonAttributeDao, ldapperpersonattributedao, etc
Therefore, SingleRowJdbcPersonAttributeDao can also be configured in deployerConfigContext.xml
That is, < bean id = "attributerepository" class="org.jasig...persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
However, I don't think it's very flexible, so I won't post the sample code
Code
Here is the user stubbersonattributedao.java of the user information returned by the custom control
package com.jadyer.sso.authentication; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.jasig.services.persondir.IPersonAttributes; import org.jasig.services.persondir.support.AttributeNamedPersonImpl; import org.jasig.services.persondir.support.StubPersonAttributeDao; import org.springframework.stereotype.Component; import com.jadyer.sso.model.User; /** * Customized return to client related information * Created by Xuanyu < https://jadier.github.io/ > on 2015 / 07 / 18 17:52 */ @Component(value="attributeRepository") public class UserStubPersonAttributeDao extends StubPersonAttributeDao { @Resource private UserDaoJdbc userDaoJdbc; @Override public IPersonAttributes getPerson(String uid) { Map<String, List<Object>> attributes = new HashMap<String, List<Object>>(); try { User user = userDaoJdbc.getByUsername(uid); attributes.put("userId", Collections.singletonList((Object)user.getUsercode())); attributes.put("username", Collections.singletonList((Object)user.getUsername())); attributes.put("usernamePlain", Collections.singletonList((Object)URLEncoder.encode(user.getUsernamePlain(), "UTF-8"))); attributes.put("blogURL", Collections.singletonList((Object)"https://jadyer.github.io/")); attributes.put("blogger", Collections.singletonList((Object)URLEncoder.encode("Xuan Yu", "UTF-8"))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new AttributeNamedPersonImpl(attributes); } }
Here is the UserDaoJdbc.java used to query the database
package com.jadyer.sso.authentication; import java.sql.ResultSet; import java.sql.SQLException; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import com.jadyer.sso.model.User; @Repository public class UserDaoJdbc { private static final String SQL_USER_VERIFY = "SELECT COUNT(*) FROM permission_operator WHERE operator_login=? AND operator_pwd=SHA1(?)"; private static final String SQL_USER_GET = "SELECT * FROM permission_operator WHERE operator_login=?"; private JdbcTemplate jdbcTemplate; @Resource public void setDataSource(DataSource dataSource){ this.jdbcTemplate = new JdbcTemplate(dataSource); } public boolean verifyAccount(String username, String password){ try{ //Verify that the user name and password are correct return 1==this.jdbcTemplate.queryForObject(SQL_USER_VERIFY, new Object[]{username, password}, Integer.class); }catch(EmptyResultDataAccessException e){ return false; } } public User getByUsername(String username){ try{ //Get user information according to user name return (User)this.jdbcTemplate.queryForObject(SQL_USER_GET, new Object[]{username}, new UserRowMapper()); }catch(EmptyResultDataAccessException e){ return new User(); } } } class UserRowMapper implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int index) throws SQLException { User user = new User(); user.setUsercode(rs.getString("operator_code")); user.setUsername(rs.getString("operator_login")); user.setUsernamePlain(rs.getString("operator_name")); return user; } }
Here is the User.java used
package com.jadyer.sso.model; public class User { private String usercode; private String username; private String usernamePlain; /*-- setter And getter--*/ }
Here is the modified part of deployerConfigContext.xml
<!-- Comment out the default attributeRepository Implementation, using custom UserStubPersonAttributeDao --> <!-- <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao" p:backingMap-ref="attrRepoBackingMap" /> <util:map id="attrRepoBackingMap"> <entry key="uid" value="uid" /> <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> <entry key="groupMembership" value="groupMembership" /> </util:map> -->
Here is \ WEB-INF\view\jsp\protocol.0\casServiceValidationSuccess.jsp
<%-- Licensed to Jasig under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. Jasig licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at the following location: http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ page session="false" contentType="application/xml; charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:authenticationSuccess> <cas:user>${fn:escapeXml(assertion.primaryAuthentication.principal.id)}</cas:user> <c:if test="${not empty pgtIou}"> <cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket> </c:if> <c:if test="${fn:length(assertion.chainedAuthentications) > 1}"> <cas:proxies> <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1"> <cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> </c:forEach> </cas:proxies> </c:if> <!-- //The new part is as follows: after the validation of CASServer is successful, this page is responsible for generating the XML information that interacts with the client //The default casServiceValidationSuccess.jsp only includes the user name and does not provide other property information, so the page needs to be extended --> <c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}"> <cas:attributes> <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"> <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}> </c:forEach> </cas:attributes> </c:if> </cas:authenticationSuccess> </cas:serviceResponse>
Finally, the client obtains the index.jsp of the user-defined information returned by the server
<%@ page pageEncoding="UTF-8"%> <%@ page import="java.util.Map"%> <%@ page import="java.net.URLDecoder"%> <%@ page import="org.jasig.cas.client.util.AssertionHolder"%> <%@ page import="org.jasig.cas.client.authentication.AttributePrincipal"%> <body style="background-color:#CBE0C9;"> <span style="color:red; font-size:32px; font-weight:bold;">Client login successful</span> </body> <hr size="2"> <% AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); Map<String, Object> attributes = principal.getAttributes(); out.print("principal.getName()=" + principal.getName() + "<br/>"); out.print("request.getRemoteUser()=" + request.getRemoteUser() + "<br/>"); out.print("Login user:" + attributes.get("userId") + "<br/>"); out.print("Login time:" + AssertionHolder.getAssertion().getAuthenticationDate() + "<br/>"); out.print("-----------------------------------------------------------------------<br/>"); for(Map.Entry<String, Object> entry : attributes.entrySet()){ //When the server returns Chinese, it needs encode. When the client receives and displays Chinese, it needs decode. Otherwise, it will be garbled out.print(entry.getKey() + "=" + URLDecoder.decode(entry.getValue().toString(), "UTF-8") + "<br/>"); } out.print("-----------------------------------------------------------------------<br/>"); Map<String, Object> attributes22 = AssertionHolder.getAssertion().getAttributes(); for(Map.Entry<String, Object> entry : attributes22.entrySet()){ out.print(entry.getKey() + "=" + entry.getValue() + "<br/>"); } out.print("-----------------------------------------------------------------------<br/>"); Map<String, Object> attributes33 = AssertionHolder.getAssertion().getPrincipal().getAttributes(); for(Map.Entry<String, Object> entry : attributes33.entrySet()){ out.print(entry.getKey() + "=" + entry.getValue() + "<br/>"); } %>
Design sketch
See the next blog in this series for details on how to configure the client (including through spring)
(headache and fever today, client configuration method will be sent tomorrow)