Month: November 2015

Spring Security Custom FilterChainProxy using Java Annotation Configuration

Posted on

Source: Spring Security Custom FilterChainProxy using Java Annotation Configuration

Advertisements

Spring Security Custom FilterChainProxy using Java Annotation Configuration

Posted on Updated on

Spring 3

Hi Friends, Today we came with some interesting topics about Spring Security custom filterChainProxy with Java annotation configuration. As most of you know that after spring 4.0.X, we could do Spring configuration with annotation no more usages of XML configuration.

As my last project work, I wanted to use Java annotation configuration that completely relied on annotation so I started reading blogs and Spring official documentation then now I am able to make it possible using Annotation Configuration.

Here, below snippet code example I also provided XML configuration which is a mirror of Annotations base Configuration file. In this snippet code example, three login windows are required for USER, RECRUITER and ADMIN login so accordingly it is configured.

Custom Implemented Classes:-

  • LoginSuccessDispatcherHandler : – This class dispatch the page after successful authentication to target page i.e if LoginType is ROLE_USER then redirect to user dashboard or if LoginType is ROLE_RECRUITE then redirect to recruiter dashboard or  if LoginType is ROLE_ADMIN then redirect to admin dashboard.
  • UserAuthenticationProvider :- This class implemented from AbstractUserDetailsAuthenticationProvider  that validate token and return a valid User Object.

Annotation base configuration here:-


package com.itexperts.spring.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.ServletException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.intercept.RunAsManager;
import org.springframework.security.access.intercept.RunAsManagerImpl;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.access.expression.ExpressionBasedFilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import com.itexperts.spring.bean.UserAuth;
import com.itexperts.spring.security.LoginSuccessDispatcherHandler;
import com.itexperts.spring.security.UserAuthenticationProvider;

@Configuration
@EnableWebSecurity
public class AppSecurityConfig  {

	@Bean
	public AuthenticationManager getAuthenticationManager() {
		AuthenticationManager authenticationManager = new ProviderManager(
				Arrays.asList(getAuthenticationProvider()));
		return authenticationManager;
	}

	@Bean
	public AuthenticationProvider getAuthenticationProvider() {
		UserAuthenticationProvider userAuthenticationProvider = new UserAuthenticationProvider();
		return userAuthenticationProvider;
	}
	
	@Bean
    public SaltSource saltSource() throws Exception {
        ReflectionSaltSource saltSource = new ReflectionSaltSource();
        saltSource.setUserPropertyToUse("salt");
    saltSource.afterPropertiesSet();
    return saltSource;
}

@Bean(name="springSecurityFilterChain")
public FilterChainProxy getFilterChainProxy() throws ServletException, Exception {
	List listOfFilterChains = new ArrayList();
	listOfFilterChains.add(new DefaultSecurityFilterChain(
			new AntPathRequestMatcher("/home**")));
	listOfFilterChains.add(new DefaultSecurityFilterChain(
			new AntPathRequestMatcher("/resources/**")));
	listOfFilterChains.add(new DefaultSecurityFilterChain(
			new AntPathRequestMatcher("/**"),
			securityContextPersistenceFilter(), logoutFilter(),
			usernamePasswordAuthenticationFilter(),
			exceptionTranslationFilter(), filterSecurityInterceptor()));
	return new FilterChainProxy(listOfFilterChains);
}

@Bean
public SecurityContextPersistenceFilter securityContextPersistenceFilter() {
	return new SecurityContextPersistenceFilter(
			new HttpSessionSecurityContextRepository());
}

@Bean
public ExceptionTranslationFilter exceptionTranslationFilter() {
	ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(
			new LoginUrlAuthenticationEntryPoint("/home"));
	AccessDeniedHandlerImpl accessDeniedHandlerImpl = new AccessDeniedHandlerImpl();
	accessDeniedHandlerImpl.setErrorPage("/exception");
	exceptionTranslationFilter
			.setAccessDeniedHandler(accessDeniedHandlerImpl);
	exceptionTranslationFilter.afterPropertiesSet();
	return exceptionTranslationFilter;
}


@Bean
public AbstractAuthenticationProcessingFilter usernamePasswordAuthenticationFilter()
		throws Exception {
	AbstractAuthenticationProcessingFilter usernamePasswordAuthenticationFilter = new UsernamePasswordAuthenticationFilter();
	usernamePasswordAuthenticationFilter
			.setAuthenticationManager(getAuthenticationManager());
	// super(new AntPathRequestMatcher("/login", "POST"));->
	//usernamePasswordAuthenticationFilter.setFilterProcessesUrl("/login");
	usernamePasswordAuthenticationFilter.setAllowSessionCreation(true);

	AuthenticationSuccessHandler successHandler = new LoginSuccessDispatcherHandler();
	usernamePasswordAuthenticationFilter
			.setAuthenticationSuccessHandler(successHandler);
	usernamePasswordAuthenticationFilter
			.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler(
					"/home?error=true"));
	usernamePasswordAuthenticationFilter.afterPropertiesSet();

	return usernamePasswordAuthenticationFilter;

}

@Bean
public LogoutFilter logoutFilter() throws ServletException {
	List handlers = new ArrayList();
	handlers.add(new CookieClearingLogoutHandler("JSESSIONID"));
	handlers.add(new SecurityContextLogoutHandler());
	LogoutFilter logoutFilter = new LogoutFilter("/logout",
			handlers.toArray(new LogoutHandler[] {}));
	logoutFilter.afterPropertiesSet();
	return logoutFilter;
}

 @Bean
 public FilterSecurityInterceptor filterSecurityInterceptor()
            throws Exception {
        FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
        filterSecurityInterceptor
                .setAuthenticationManager(getAuthenticationManager());
        filterSecurityInterceptor
                .setAccessDecisionManager(accessDecisionManager());
        filterSecurityInterceptor.setRunAsManager(runAsManager());
        LinkedHashMap<RequestMatcher, Collection> requestMap = new LinkedHashMap<RequestMatcher, Collection>();
      
        requestMap.put(new AntPathRequestMatcher("/user/**"), 
        		SecurityConfig.createList("hasRole('"+UserAuth.ROLE_CANDIDATE.name()+"')"));
        requestMap.put(new AntPathRequestMatcher("/recruiter/**"), 
        		SecurityConfig.createList("hasRole('"+UserAuth.ROLE_RECRUITER.name()+"')"));
        requestMap.put(new AntPathRequestMatcher("/admin/**"), 
        		SecurityConfig.createList("hasRole('"+UserAuth.ROLE_ADMIN.name()+"')"));
        FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource = new ExpressionBasedFilterInvocationSecurityMetadataSource(
                requestMap, new DefaultWebSecurityExpressionHandler());
        filterSecurityInterceptor
                .setSecurityMetadataSource(filterInvocationSecurityMetadataSource);
        filterSecurityInterceptor.afterPropertiesSet();

        return filterSecurityInterceptor;
    }
 
 public AffirmativeBased accessDecisionManager() throws Exception {
        List<AccessDecisionVoter<? extends Object>> voters = new ArrayList<AccessDecisionVoter<? extends Object>>();
        voters.add(new WebExpressionVoter());
        RoleVoter voter = new RoleVoter();
        voter.setRolePrefix("ROLE_");
        voters.add(voter);
        voters.add(new AuthenticatedVoter());
        AffirmativeBased affirmativeBased = new AffirmativeBased(voters);
        affirmativeBased.setAllowIfAllAbstainDecisions(false);
        affirmativeBased.afterPropertiesSet();

        return affirmativeBased;
    }

    @Bean
    public RunAsManager runAsManager() throws Exception {
        RunAsManagerImpl runAsManager = new RunAsManagerImpl();
        runAsManager.setKey("ROLE_ADMIN");
	        runAsManager.afterPropertiesSet();
	        return runAsManager;
	    }
}

XML configuration here :-


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:security="http://www.springframework.org/schema/security"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 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">

 <alias name="filterChainProxy" alias="springSecurityFilterChain"/>
 
 <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
 
 <security:filter-chain-map path-type="ant">
 
 
 <security:filter-chain pattern="/home/**" filters="none" />
 <security:filter-chain pattern="/resources/**" filters="none" />
 
 <security:filter-chain pattern="/**" filters="concurrentSessionFilter,securityContextPersistenceFilter,logoutFilter,authenticationFilter,sessionManagementFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
 </security:filter-chain-map>
 </bean>
 
 <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
 <property name="providers">
 <list>
 <ref local="userAuthenticationProvider" />
 </list>
 </property>
 </bean>
 
 <bean id="userAuthenticationProvider" class="com.itexperts.spring.security.UserAuthenticationProvider">
 </bean>

 <bean id="securityContextPersistenceFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
 <property name="securityContextRepository" ref="securityContextRepository" />
 </bean>
 
 <bean id="securityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />

 <bean id="concurrentSessionFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
 <property name="expiredUrl" value="/home?errorCode=24" />
 <property name="sessionRegistry" ref="sessionRegistry" />
 </bean>

 

 <bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
 
 <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
 <constructor-arg value="/logout" />
 <!-- URL redirected to after logout -->
 <constructor-arg>
 <list>
 <bean
 class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
 </bean>
 </list>
 </constructor-arg>
 </bean>

 <bean id="authenticationFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
 <property name="authenticationManager" ref="authenticationManager" />
 <!--<property name="filterProcessesUrl" value="/login" />-->
 <property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
 <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
 <property name="sessionAuthenticationStrategy" ref="sas" />
 </bean>

 <bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
 <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
 </bean>

 
 <bean id="authenticationEntryPoint" class="com.search.job.authentication.manager.AjaxAwareAuthenticationEntryPoint">
 <property name="loginFormUrl" value="/home" />
 </bean>
 
 <bean id="accessDeniedHandler" class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
 <property name="errorPage" value="/exception" />
 </bean>

 <bean id="authenticationSuccessHandler" class="com.itexperts.spring.security.LoginSuccessDispatcherHandler">
 </bean>

 <bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
 <constructor-arg name="sessionRegistry" ref="sessionRegistry" />
 <property name="maximumSessions" value="1" />
 </bean>
 

 <bean id="filterSecurityInterceptor"
 class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
 <property name="authenticationManager">
 <ref bean="authenticationManager" />
 </property>
 <property name="accessDecisionManager">
 <bean class="org.springframework.security.access.vote.AffirmativeBased">
 <property name="decisionVoters">
 <list>
 <bean class="org.springframework.security.access.vote.RoleVoter">
 <property name="rolePrefix" value="ROLE_" />
 </bean>
 <bean
 class="org.springframework.security.access.vote.AuthenticatedVoter">
 </bean>

 </list>
 </property>
 </bean>
 </property>
 <property name="securityMetadataSource">
 <security:filter-security-metadata-source>
 <security:intercept-url pattern="/profile/**" access="ROLE_CANDIADTE"></security:intercept-url>
 <security:intercept-url pattern="/recruiter/**" access="ROLE_RECRUITER"></security:intercept-url>
 <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN"></security:intercept-url>
 </security:filter-security-metadata-source>
 </property>
 </bean>
 
 <bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
 <constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
 <property name="sessionAuthenticationStrategy" ref="sas" />
 </bean>
 <bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/> 
</beans>


Finally, we need to register all Servlets and Filter and other in web.xml, Since we are using Annotation base configuration so that we do it following way:-


package com.itexperts.spring.dispatcher;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.itexperts.spring.config.AppConfig;
import com.itexperts.spring.config.AppSecurityConfig;
import com.itexperts.spring.config.ServletContextConfig;

public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		
		return new Class[]{AppConfig.class,AppSecurityConfig.class};
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[]{ServletContextConfig.class};
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}
	
	@Override
    public void onStartup(ServletContext servletContext) 
            throws ServletException {
        servletContext
            .addFilter("springSecurityFilterChain", 
                       new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");

        super.onStartup(servletContext);
    }

}

LoginSuccessDispatcherHandler.Java


package com.itexperts.spring.security;

import java.io.IOException;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.itexperts.spring.bean.UserAuth;

public class LoginSuccessDispatcherHandler implements
		AuthenticationSuccessHandler {

	private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request,
			HttpServletResponse response, Authentication authentication)
			throws IOException {
		handle(request, response, authentication);
		clearAuthenticationAttributes(request);
	}

	protected void handle(HttpServletRequest request,
			HttpServletResponse response, Authentication authentication)
			throws IOException {
		String targetUrl = determineTargetUrl(authentication);

		if (response.isCommitted()) {
			return;
		}

		redirectStrategy.sendRedirect(request, response, targetUrl);
	}

	protected String determineTargetUrl(Authentication authentication) {

		Collection<? extends GrantedAuthority> authorities = authentication
				.getAuthorities();
		String targetURL = "";
		for (GrantedAuthority auth : authorities) {
			if (auth.getAuthority().equals(UserAuth.ROLE_CANDIDATE.name())) {
				targetURL = "/user/candidate";
				break;
			} else if (auth.getAuthority().equals(
					UserAuth.ROLE_RECRUITER.name())) {
				targetURL = "/recruiter";
				break;
			} else if (auth.getAuthority().equals(UserAuth.ROLE_ADMIN.name())) {
				targetURL = "/admin";
				break;
			} else {
				break;
			}
		}
		if ("".equals(targetURL)) {
			throw new IllegalStateException();
		}
		return targetURL;

	}

	protected void clearAuthenticationAttributes(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return;
		}
		session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
	}

	public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
		this.redirectStrategy = redirectStrategy;
	}

	protected RedirectStrategy getRedirectStrategy() {
		return redirectStrategy;
	}

}


UserAuthenticationProvider.Java


package com.itexperts.spring.security;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

import com.itexperts.spring.bean.LoginModel;
import com.itexperts.spring.repo.UserRepository;

public class UserAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

	@Autowired
	private UserRepository userRepository;
	
	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken token)
			throws AuthenticationException {
	}

	@Override
	protected UserDetails retrieveUser(String str,
			UsernamePasswordAuthenticationToken token)
			throws AuthenticationException {
		LoginModel loginModel = userRepository.login(token.getPrincipal(),token.getCredentials());
		if( loginModel == null ){
			throw new BadCredentialsException("Invalid Username and Password");
		}
		Collection grantedAuthorities = new ArrayList();
		GrantedAuthority roleType = new SimpleGrantedAuthority(loginModel.getUsertype());
		grantedAuthorities.add(roleType);
		return new User(loginModel.getUsername(), loginModel.getPassword(),true, true, true, true, grantedAuthorities);
	}

}


Inventory Example with AngularJS

Posted on Updated on

angularjs

 

 

 

 

Another AngularJS sample example of inventory system which give you better glance about single page application development, we do not use any validation in this example, will covert in next topics.

Better you download it and run on your system.

 

inventory-angular

This method ( ‘AddInCart’) gets called when use enter ‘Add in Cart’ button, extract ng-model values one by one and calculate total price as per item selected price multiply by quantity.
In the next line, create a JSON object with key and value and insert into array  ‘cartItems‘.

$scope.AddInCart = function() {
 var itemName = $scope.item.name;
 var itemPrice = parseInt($scope.item.price);
 var itemQty = parseInt($scope.qty);
 var totalPrice = parseInt(itemPrice * itemQty);
 var jsonCartItem = {
 'name' : itemName,
 'price' : itemPrice,
 'qty' : itemQty,
 'totAmt' : totalPrice
 };
 $scope.cartItems.push(jsonCartItem);
 }

This method gets called when user wanted to remove item from cart. Javascript method “splice” is used to add or remove the element from array.

 $scope.removeCartItem = function(index){
 $scope.cartItems.splice(index,1);
 }

This method called inline whenever a new Items has been added or deleted into Cart Array then this method fired.

 $scope.subTotalAmt = function(){
 var cartItemsLength = $scope.cartItems.length;
 var totAmt =0.0;
 if(cartItemsLength>0){
   for(var i=cartItemsLength-1;i>=0;i--){
      totAmt += parseInt($scope.cartItems[i].totAmt);
   }
 }
 return totAmt;
 }

Complete code below :-

<!DOCTYPE html >
<html ng-app="dashboard">
<head>
<title>AngularJS</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js
https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js
</head>
<body ng-controller="myController">
 
 <h1>Welcome to Inventory Example with AngularJS</h1>
<table border='1'>
 <tr>
 <td colspan='2'>
 <h2>Select Items</h2>
 </td>
 </tr>
 <tr>
 <td>Items</td>
 <td><select ng-model="item"
 ng-options="item.name for item in items"
 ng-change="getPriceList(item);" readonly>
 </select></td>
 </tr>
 <tr>
 <td>Price</td>
 <td><input type="test" ng-model="item.price" readonly></td>
 </tr>
 <tr>
 <td>Qty</td>
 <td><select ng-model="qty" ng-options="q for q in itemQty" readonly>

 </select></td>
 </tr>
 <tr>
 <td colspan="2"><input type="button" ng-click="AddInCart()"
 value="Add in Cart">
 </tr>
 </table>
 
 <h2>Cart Items</h2>
 
<table style="width:60%;">
 <thead>
 <tr>
 <th>Name</th>
 <th>Price per Unit</th>
 <th>Quantity</th>
 <th>Total Amount</th>
 <th>Remove Item</th>
 </tr>
 </thead>
 <tbody>
 <tr ng-repeat="cart in cartItems">
 <td>{{cart.name}}</td>
 <td>{{cart.price}}</td>
 <td>{{cart.qty}}</td>
 <td>{{cart.totAmt}}</td>
 <th><a href ng-click="removeCartItem($index)"><span class="glyphicon glyphicon-remove-circle"></a></span>
 </tr>
 <tr class="panel panel-info">
 <th colspan="3" align="right">Total Amt:</th>
 <th colspan="2">{{subTotalAmt()}}</th>
 <tr>
 </tbody>
 </table>
</body>
// Javascript start here 
 
 var dashboard = angular.module("dashboard", []);

 dashboard.controller('myController', function($scope) {
 $scope.items = [ {
 'name' : 'Computer',
 'price' : 20000
 }, {
 'name' : 'RAM',
 'price' : 2000
 }, {
 'name' : 'CPU',
 'price' : 10000
 }, {
 'name' : 'Mouse',
 'price' : 200
 }, {
 'name' : 'Keyboard',
 'price' : 500
 } ];
 $scope.itemQty = [ 1, 2, 3, 4, 5, 6 ];
 $scope.cartItems = [];

 $scope.getPriceList = function(item) {
 $scope.item.price = item.price;
 }

 $scope.AddInCart = function() {
 var itemName = $scope.item.name;
 var itemPrice = parseInt($scope.item.price);
 var itemQty = parseInt($scope.qty);
 var totalPrice = parseInt(itemPrice * itemQty);
 var jsonCartItem = {
 'name' : itemName,
 'price' : itemPrice,
 'qty' : itemQty,
 'totAmt' : totalPrice
 };
 $scope.cartItems.push(jsonCartItem);

 }
 $scope.removeCartItem = function(index){
 $scope.cartItems.splice(index,1);
 }
 
 $scope.subTotalAmt = function(){
 var cartItemsLength = $scope.cartItems.length;
 var totAmt =0.0;
 if(cartItemsLength>0){
   for(var i=cartItemsLength-1;i>=0;i--){
      totAmt += parseInt($scope.cartItems[i].totAmt);
   }
 }
 return totAmt;
 }
 });
 
// Javascript end here with  tag
</html>
 

Please find complete code from google drive :- https://drive.google.com/file/d/0B8SgSioNRbwcNERQdll3VEwycFk/view?usp=sharing