UserServiceImpl:SAML AuthnResponse不被解碼
@Override public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException{ String userID = credential.getNameID().getValue(); logger.info(userID + " is logged in"); List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER"); authorities.add(authority); List<Attribute> userAttributes = credential.getAttributes(); logger.info("Credential attributes: " + userAttributes); for (int attrIndex = 0; attrIndex < userAttributes.size(); attrIndex++) { Attribute attr = userAttributes.get(attrIndex); List<XMLObject> attrValues = attr.getAttributeValues(); StringBuilder strBuilder = new StringBuilder(); for (int attrValueIndex = 0; attrValueIndex < attrValues.size(); attrValueIndex++) { XMLObject currObj = attrValues.get(attrValueIndex); strBuilder.append(currObj.toString()).append(","); } strBuilder.deleteCharAt(strBuilder.length() - 1); logger.info(attr.getFriendlyName() + ", " + strBuilder.toString()); String samlAttrValue = strBuilder.toString(); switch (attr.getFriendlyName()) { case "userName": samlUserAttribute.setUserName(samlAttrValue); case "email": samlUserAttribute.setEmail(samlAttrValue); break; case "firstName": samlUserAttribute.setFirstName(samlAttrValue); break; case "lastName": samlUserAttribute.setLastName(samlAttrValue); break; case "userType": samlUserAttribute.setUserType(samlAttrValue); break; case "accountName": samlUserAttribute.setAccountName(samlAttrValue); break; case "contactId": samlUserAttribute.setContactId(samlAttrValue); break; default: logger.info("invalid attribute name" + attr.getFriendlyName()); } } logger.info("User details obtained: " + samlUserAttribute); return new SamlUserDTO(userID, "<abc123>", authorities, samlUserAttribute); }
的UserDetails實現:
private SamlUserAttribute currentUserAttribute; private String password; private final String username; private final Set<GrantedAuthority> authorities; private final boolean accountNonExpired; private final boolean accountNonLocked; private final boolean credentialsNonExpired; private final boolean enabled; .. setter/getter/contructors for userDetails...
3.Security-配置細節
<security:http entry-point-ref="samlEntryPoint" access-decision-manager-ref="accessDecisionManager" authentication-manager-ref="authenticationManager" use-expressions="true"> <security:intercept-url pattern="/login" access="permitAll"/> <security:intercept-url pattern="/**" access="isFullyAuthenticated()" /> <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter" /> <security:csrf disabled="true"/> </security:http> <bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy"> <security:filter-chain-map request-matcher="ant"> <security:filter-chain pattern="/**" filters="samlEntryPoint" /> </security:filter-chain-map> </bean> <bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider"> <property name="userDetails" ref="UserServiceImpl" /> <property name="forcePrincipalAsString" value="false" /> </bean> <bean id="UserServiceImpl" class="com.akamai.marketplace.service.impl.common.UserServiceImpl"> </bean>
在瀏覽所需的URL時,我可以在瀏覽器上看到IDP重定向發生,IDP回覆所需的斷言,並且登錄URL爲/ login 但是在我的/ login控制器中,Authentication Object的UserDetail沒有填充自定義數據。
/登錄控制器:
@RequestMapping(path="/login",method = RequestMethod.POST) public ResponseEntity<SamlUserDTO> login() { logger.info("login API reached through IdP."); Authentication userAuthentication = SecurityContextHolder.getContext().getAuthentication(); logger.info("user details: "+userAuthentication.getDetails()); logger.info("user credentials: "+userAuthentication.getCredentials()); logger.info("principal " + userAuthentication.getPrincipal()); SamlUserDTO samlUserDTO1 = (SamlUserDTO) userAuthentication.getPrincipal(); return ResponseEntity.ok(samlUserDTO1); }
日誌:
2016年8月11日十七時22分16秒DEBUG BaseMessageEncoder:56 - 成功編碼的消息。 2016年8月11日17點22分16秒DEBUG HttpSessionStorage:93 - 存儲消息a399ehchh04afi304hih7e49fd791g2到會話someValue中
2016年8月11日17點22分16秒INFO SAMLDefaultLogger:127 - AuthNRequest; SUCCESS; someIP; SP-ENTITYID ; IDP-ENTITYID ;;;
2016-08-11 17:22:37 INFO UserController:18 - 登錄API通過IdP達到。
2016-08-11 17:22:37 INFO UserController:20 - 用戶詳細信息:org.sprin[email protected]ffffa64e:RemoteIpAddress:Idp-IpAddress; SESSIONID:someValue中
2016年8月11日17時22分37秒INFO UserController中:21 - 用戶憑證:
2016年8月11日17時22分37秒INFO UserController中:22 - 主要anonymousUser 2016-08 -11 17:22:37 DEBUG ExceptionHandlerExceptionResolver:133 - 解決處理異常[public org.springframework.http.ResponseEntity com.akamai.marketplace.controller.UserController.login()]:java.lang.ClassCastException:java.lang。字符串不能轉換爲controller.model.SamlUserDTO
2016-08-11 17:22:37 DEBUG ExceptionHandlerExceptionResolver:361 - 調用@ExceptionHandler方法:public org.springframework.http.ResponseEntity R ESTExceptionHandler.handleExeption(java.lang.Exception) 2016-08-11 17:22:37 ERROR RESTExceptionHandler:60 - 由異常處理程序捕獲的異常: java.lang.ClassCastException:無法將java.lang.String強制轉換爲包。 SamlUserDTO