'accesscontrol'에 해당되는 글 2건

  1. 2012.08.17 xacml 확장하기. html element 에 대한 ACL 적용
  2. 2012.08.16 xacml 웹 적용하기
2012. 8. 17. 20:35 IT

배경 : xacml 을 버튼에 대해서도 적용해달란다.

이미 적용된 상태에서 또다른 솔루션 (spring security 등등)을 적용하는 경우 관리 비용이 증가할 것을 우려하여, 한곳에서 관리하고 싶어했다. 


구현방향 : interceptor대신 validation을 처리할 controller 와 javascript function 을 제공. 


1. javascript로 object (button, image etc.. ) 의 id를  전달.

2. controller에 해당 object 에 대한 권한 여부를 확인

3. 결과에 따라 disable, enable 처리


단점 : 

- 버튼 권한까지 서버에게 물어봐야 하니???

- id가 중복될 경우 잘못 처리될 수 있음.


구현내용

1. javascript function

$.authorizeWebElement = function(objectid){

$.ajax({

type: "POST",

dataType: "json",

url:  "/authorize" ,

data : {"objectId":objectid},

success: function(data){

$(objectid)[data.message]();

}

});

};


2. controller

public @ResponseBody Map<String, Object> authorize(@RequestParam(value="objectId") String objectId, HttpServletRequest request){

ACManager acm = ACManager.getInstance(this.pdpPath); 

                List<String> roles = getRoles(request); // get user role from session or persistence data 

                Map map = new HashMap(); 

if(acm.evaluate(roles, objectId)){

map.put("message ", " show");

}else{

map.put("message ", " hide");

}

return map;

}


3. screen 

function xxx(){

    $.authorizeUI("#OnlyAdminAvailableButton");

}


cf) 주의사항 

반드시 elementId 는 유일해야한다. ...

posted by smplnote
2012. 8. 16. 09:08 IT

목적 : Access Control 표준이 XACML 이란다.


경과 : 

몇가지 xacml 관련 구현체들을 찾아보았는데,

상용이 아닌 것으로 가장 활발한 곳은 jboss xacml 구현체인 picketbox 였다. 

Picketbox는  Java Security Framework의 하나인데,  Oasis XACML v2.0 에 호환되는 엔진을 제공한다. 



절차 


1. xacml library download

from http://www.jboss.org/picketbox/downloads

jbossxacml-2.0.8.Final.jar


2. add library 

WEB-INF/lib 또는 기타 classpath 상에 해당 jar 파일을 배치한다.


3. register ACL Interceptor to spring mvc context 

> context/servlet-context.xml

<mvc:interceptors>        <mvc:mapping path="/*"/>                    

                     <bean class="com.MyACLInterceptor" >

                     <property name="config" value="config/policyConfig.xml"/><!-- pdp file classpath -->

                      </bean>

</mvc:interceptor>

...

</mvc:interceptors> 

4. write PDP (Policy Decision Point)  configuration file
Caching과 관련해서는 아래 Reference 를 참조

> config/policyConfig.xml

<ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0">

           <ns:Policies>

                     <ns:PolicySet>

                                <ns:Location>config/mypolicyset.xml</ns:Location>

                     </ns:PolicySet>

           </ns:Policies>

<ns:Locators>

<ns:Locator Name="org.jboss.security.xacml.locators.JBossPolicySetLocator"/>

</ns:Locators>

</ns:jbosspdp>

5. policy set 정의

> config/mypolicyset.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<PolicySet xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"  PolicySetId="policyset"

  PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:first-applicable">

           <Target />

           <Policy xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"

                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                     xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os

        access_control-xacml-2.0-policy-schema-os.xsd"

                     PolicyId="my-policy"

                     RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">

                     <Description>access control policy</Description>

                     <Target />

 <Rule RuleId="myruleid" Effect="Permit"><!— Permit / Deny  -->

           <Description>my rule</Description>

           <Target >

           <Subjects/>

           <Resources> 

                    <Resource> 

                              <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> 

                                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">^/( accessuri1|accessuri2)</AttributeValue> 

                                        <ResourceAttributeDesignator 

                                        AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> 

                                        </ResourceMatch> 

        </Resource> 

         </Resources> 

           </Target>

           <Condition>

                      <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-is-in">

                                <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ACCESSIBLE_ROLE_NAME</AttributeValue>

                                <SubjectAttributeDesignator

                                          DataType="http://www.w3.org/2001/XMLSchema#string" AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" />

                     </Apply>

           </Condition>

</Rule>

. . . 

<Rule RuleId="ImplicitDeny" Effect="Deny" />

</Policy>

</PolicySet>


-   policy-combining-algorithm은 경우에 따라 적절하게 사용할 것. ( first-applicable은 첫번째 걸리는 Rule을 따른다는 의미 )

- Rule의 Effect는 Permit 아니면 Deny 를 선택할수 있음

ResourceMatch  로 대상 Resource 를 정의할 수 있음

Condition 으로 Rule의 detail을 표현할 수 있음


cf) Policy 작성 BP. ( Ref. 1 - 2.7 )

- policy와 file 이름을 동일하게.

- 룰 조합 규칙은 가능한 심플하게. first-applicable 권고

- Permit, Deny 를 섞기말고 가능한 한쪽으로 모는것이 좋음. 


6. Interceptor 작성

MyACLInterceptor.java

public class MyACLInterceptor extends HandlerInterceptorAdapter {

private String config = "";

public  String getConfig(){

return this.config;

}

public void setConfig(String config){

this.config = config;

}

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

if (!hasAccessRole(request)) {

throw new Exception("access not allowed.");

}

return true;

}

private boolean hasAccessRole(HttpServletRequest request) {
String  resourceId  = request.getRequestURI(); // URI
List<String> userRoles = getUserRoles(request); // User ROLES
ACLManager acm = ACLManager.getInstance(this.config); 
return acm.evaluate(userRoles, resourceId);
}
        List<String> getUserRoles(HttpServletRequest request){
              return "get user role from session or persistence data".....
        }
}


7. ACLManager 작성


public class ACLManager {

private static ACLManager instance;

private PolicyDecisionPoint pdp = null;

public boolean evaluate(List<String>userRoles, String resourceId) throws Exception{

RequestContext request = createXACMLRequest(userRoles, resourceId);

// try { request.marshall(System.out); } catch (IOException e) { }

ResponseContext response = this.pdp.evaluate(request);

return XACMLConstants.DECISION_PERMIT == response.getDecision();

}


public RequestContext createXACMLRequest(List<String>userRoles, String resourceId) throws Exception{

RequestContext requestCtx = RequestResponseContextFactory.createRequestCtx();

     SubjectType subject = new SubjectType();

     subject.getAttribute().add(RequestAttributeFactory.createStringAttributeType(XACMLConstants.ATTRIBUTEID_SUBJECT_ID, "myissuer", "mysubject"));

     for(String role : userRoles) {

        AttributeType attSubjectID = RequestAttributeFactory.createStringAttributeType(XACMLConstants.ATTRIBUTEID_ROLE, "myissuer", role);

        subject.getAttribute().add(attSubjectID);

     }

     ResourceType resourceType = new ResourceType();

     resourceType.getAttribute().add(RequestAttributeFactory.createStringAttributeType(XACMLConstants.ATTRIBUTEID_RESOURCE_ID, null, resourceId ));

     

     ActionType actionType = new ActionType();

     actionType.getAttribute().add(RequestAttributeFactory.createStringAttributeType("action-id", "myissuer", "read"));


     RequestType requestType = new RequestType();

     requestType.getSubject().add(subject);

     requestType.getResource().add(resourceType);

     requestType.setAction(actionType);

     requestCtx.setRequest(requestType);

return requestCtx;

}

private void setPDP(String pdpPath) throws Exception {

  InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(pdpPath);

  this.pdp = new JBossPDP(is); 

}

private ACLManager(String pdpPath) throws Exception{

setPDP(pdpPath);

}

public static synchronized ACLManager getInstance(String pdpPath) throws Exception{

if (instance == null) {

instance = new ACLManager(pdpPath);

}

return instance;

}

}



[References]

1) XACML Function List : http://fedora-commons.org/download/2.2/userdocs/server/security/XACMLPolicyGuide.htm 

XACML caching for Performance : https://community.jboss.org/wiki/XACMLCachingForPerformance


posted by smplnote